Merge "Revert "Add statsd logging to perfetto_cmd""
diff --git a/Android.bp b/Android.bp
index 514776e..c1be406 100644
--- a/Android.bp
+++ b/Android.bp
@@ -27,7 +27,6 @@
"src/trace_processor/metrics/android/android_mem_unagg.sql",
"src/trace_processor/metrics/android/android_package_list.sql",
"src/trace_processor/metrics/android/android_powrails.sql",
- "src/trace_processor/metrics/android/android_process_growth.sql",
"src/trace_processor/metrics/android/android_startup.sql",
"src/trace_processor/metrics/android/android_startup_cpu.sql",
"src/trace_processor/metrics/android/android_startup_launches.sql",
@@ -36,6 +35,7 @@
"src/trace_processor/metrics/android/java_heap_stats.sql",
"src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql",
"src/trace_processor/metrics/android/process_mem.sql",
+ "src/trace_processor/metrics/android/process_metadata.sql",
"src/trace_processor/metrics/android/process_unagg_mem_view.sql",
"src/trace_processor/metrics/android/span_view_stats.sql",
"src/trace_processor/metrics/android/unsymbolized_frames.sql",
@@ -95,14 +95,14 @@
":perfetto_protos_perfetto_config_sys_stats_zero_gen",
":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_zero_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_minimal_zero_gen",
":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
":perfetto_protos_perfetto_trace_perfetto_zero_gen",
@@ -111,7 +111,6 @@
":perfetto_protos_perfetto_trace_ps_zero_gen",
":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_src_base_base",
":perfetto_src_base_unix_socket",
":perfetto_src_ipc_ipc",
@@ -168,14 +167,14 @@
"perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_zero_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
"perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
@@ -184,7 +183,6 @@
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
"perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
],
defaults: [
"perfetto_defaults",
@@ -304,14 +302,14 @@
":perfetto_protos_perfetto_config_sys_stats_zero_gen",
":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_zero_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_minimal_zero_gen",
":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
":perfetto_protos_perfetto_trace_perfetto_zero_gen",
@@ -320,7 +318,6 @@
":perfetto_protos_perfetto_trace_ps_zero_gen",
":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_src_android_internal_headers",
":perfetto_src_android_internal_lazy_library_loader",
":perfetto_src_base_base",
@@ -386,14 +383,14 @@
"perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_zero_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
"perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
@@ -402,7 +399,6 @@
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
"perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
],
defaults: [
"perfetto_defaults",
@@ -492,14 +488,14 @@
":perfetto_protos_perfetto_config_sys_stats_zero_gen",
":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_zero_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_minimal_zero_gen",
":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
":perfetto_protos_perfetto_trace_perfetto_zero_gen",
@@ -508,7 +504,6 @@
":perfetto_protos_perfetto_trace_ps_zero_gen",
":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_src_base_base",
":perfetto_src_base_unix_socket",
":perfetto_src_ipc_ipc",
@@ -558,14 +553,14 @@
"perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_zero_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
"perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
@@ -574,7 +569,6 @@
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
"perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
],
export_generated_headers: [
"perfetto_protos_perfetto_common_cpp_gen_headers",
@@ -608,14 +602,14 @@
"perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_zero_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
"perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
@@ -624,7 +618,6 @@
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
"perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
],
defaults: [
"perfetto_defaults",
@@ -679,14 +672,14 @@
":perfetto_protos_perfetto_config_sys_stats_zero_gen",
":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_zero_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_minimal_zero_gen",
":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
":perfetto_protos_perfetto_trace_perfetto_zero_gen",
@@ -695,7 +688,6 @@
":perfetto_protos_perfetto_trace_ps_zero_gen",
":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_src_android_internal_headers",
":perfetto_src_android_internal_lazy_library_loader",
":perfetto_src_base_base",
@@ -747,14 +739,14 @@
"perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_zero_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
"perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
@@ -763,7 +755,6 @@
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
"perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
"perfetto_src_perfetto_cmd_protos_gen_headers",
],
defaults: [
@@ -932,7 +923,8 @@
":perfetto_protos_perfetto_config_sys_stats_zero_gen",
":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_zero_gen",
":perfetto_protos_perfetto_trace_android_lite_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_lite_gen",
@@ -961,7 +953,6 @@
":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_track_event_lite_gen",
":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_src_android_internal_headers",
":perfetto_src_android_internal_lazy_library_loader",
":perfetto_src_base_base",
@@ -1044,7 +1035,8 @@
"perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_zero_gen_headers",
"perfetto_protos_perfetto_trace_android_lite_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
@@ -1073,7 +1065,6 @@
"perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
"perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
],
defaults: [
"perfetto_defaults",
@@ -2356,33 +2347,71 @@
],
}
-// GN: //protos/perfetto/ipc:wire_protocol
+// GN: //protos/perfetto/ipc:wire_protocol_cpp
genrule {
- name: "perfetto_protos_perfetto_ipc_wire_protocol_gen",
+ name: "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
srcs: [
"protos/perfetto/ipc/wire_protocol.proto",
],
tools: [
"aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/ --proto_path=external/perfetto $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/ --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=:$(genDir)/external/perfetto/ $(in)",
out: [
- "external/perfetto/protos/perfetto/ipc/wire_protocol.pb.cc",
+ "external/perfetto/protos/perfetto/ipc/wire_protocol.gen.cc",
],
}
-// GN: //protos/perfetto/ipc:wire_protocol
+// GN: //protos/perfetto/ipc:wire_protocol_cpp
genrule {
- name: "perfetto_protos_perfetto_ipc_wire_protocol_gen_headers",
+ name: "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
srcs: [
"protos/perfetto/ipc/wire_protocol.proto",
],
tools: [
"aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/ --proto_path=external/perfetto $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/ --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=:$(genDir)/external/perfetto/ $(in)",
out: [
- "external/perfetto/protos/perfetto/ipc/wire_protocol.pb.h",
+ "external/perfetto/protos/perfetto/ipc/wire_protocol.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
+}
+
+// GN: //protos/perfetto/ipc:wire_protocol_zero
+genrule {
+ name: "perfetto_protos_perfetto_ipc_wire_protocol_zero_gen",
+ srcs: [
+ "protos/perfetto/ipc/wire_protocol.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/ --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/ipc/wire_protocol.pbzero.cc",
+ ],
+}
+
+// GN: //protos/perfetto/ipc:wire_protocol_zero
+genrule {
+ name: "perfetto_protos_perfetto_ipc_wire_protocol_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/ipc/wire_protocol.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/ --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/ipc/wire_protocol.pbzero.h",
],
export_include_dirs: [
".",
@@ -2404,7 +2433,7 @@
"protos/perfetto/metrics/android/mem_unagg_metric.proto",
"protos/perfetto/metrics/android/package_list.proto",
"protos/perfetto/metrics/android/powrails_metric.proto",
- "protos/perfetto/metrics/android/process_growth.proto",
+ "protos/perfetto/metrics/android/process_metadata.proto",
"protos/perfetto/metrics/android/startup_metric.proto",
"protos/perfetto/metrics/android/unsymbolized_frames.proto",
],
@@ -2424,7 +2453,7 @@
"external/perfetto/protos/perfetto/metrics/android/mem_unagg_metric.pbzero.cc",
"external/perfetto/protos/perfetto/metrics/android/package_list.pbzero.cc",
"external/perfetto/protos/perfetto/metrics/android/powrails_metric.pbzero.cc",
- "external/perfetto/protos/perfetto/metrics/android/process_growth.pbzero.cc",
+ "external/perfetto/protos/perfetto/metrics/android/process_metadata.pbzero.cc",
"external/perfetto/protos/perfetto/metrics/android/startup_metric.pbzero.cc",
"external/perfetto/protos/perfetto/metrics/android/unsymbolized_frames.pbzero.cc",
],
@@ -2444,7 +2473,7 @@
"protos/perfetto/metrics/android/mem_unagg_metric.proto",
"protos/perfetto/metrics/android/package_list.proto",
"protos/perfetto/metrics/android/powrails_metric.proto",
- "protos/perfetto/metrics/android/process_growth.proto",
+ "protos/perfetto/metrics/android/process_metadata.proto",
"protos/perfetto/metrics/android/startup_metric.proto",
"protos/perfetto/metrics/android/unsymbolized_frames.proto",
],
@@ -2464,7 +2493,7 @@
"external/perfetto/protos/perfetto/metrics/android/mem_unagg_metric.pbzero.h",
"external/perfetto/protos/perfetto/metrics/android/package_list.pbzero.h",
"external/perfetto/protos/perfetto/metrics/android/powrails_metric.pbzero.h",
- "external/perfetto/protos/perfetto/metrics/android/process_growth.pbzero.h",
+ "external/perfetto/protos/perfetto/metrics/android/process_metadata.pbzero.h",
"external/perfetto/protos/perfetto/metrics/android/startup_metric.pbzero.h",
"external/perfetto/protos/perfetto/metrics/android/unsymbolized_frames.pbzero.h",
],
@@ -3966,40 +3995,6 @@
],
}
-// GN: //protos/perfetto/trace:trusted_lite
-genrule {
- name: "perfetto_protos_perfetto_trace_trusted_lite_gen",
- srcs: [
- "protos/perfetto/trace/trusted_packet.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/ --proto_path=external/perfetto $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/trusted_packet.pb.cc",
- ],
-}
-
-// GN: //protos/perfetto/trace:trusted_lite
-genrule {
- name: "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/trusted_packet.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/ --proto_path=external/perfetto $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/trusted_packet.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
-}
-
// GN: //protos/third_party/pprof:lite
genrule {
name: "perfetto_protos_third_party_pprof_lite_gen",
@@ -4398,6 +4393,7 @@
filegroup {
name: "perfetto_src_protozero_protozero",
srcs: [
+ "src/protozero/field.cc",
"src/protozero/message.cc",
"src/protozero/message_handle.cc",
"src/protozero/packed_repeated_fields.cc",
@@ -4405,6 +4401,55 @@
"src/protozero/scattered_heap_buffer.cc",
"src/protozero/scattered_stream_null_delegate.cc",
"src/protozero/scattered_stream_writer.cc",
+ "src/protozero/static_buffer.cc",
+ ],
+}
+
+// GN: //src/protozero:testing_messages_cpp
+genrule {
+ name: "perfetto_src_protozero_testing_messages_cpp_gen",
+ srcs: [
+ "src/protozero/test/example_proto/library.proto",
+ "src/protozero/test/example_proto/library_internals/galaxies.proto",
+ "src/protozero/test/example_proto/test_messages.proto",
+ "src/protozero/test/example_proto/upper_import.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/ --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/protozero/test/example_proto/library.gen.cc",
+ "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.gen.cc",
+ "external/perfetto/src/protozero/test/example_proto/test_messages.gen.cc",
+ "external/perfetto/src/protozero/test/example_proto/upper_import.gen.cc",
+ ],
+}
+
+// GN: //src/protozero:testing_messages_cpp
+genrule {
+ name: "perfetto_src_protozero_testing_messages_cpp_gen_headers",
+ srcs: [
+ "src/protozero/test/example_proto/library.proto",
+ "src/protozero/test/example_proto/library_internals/galaxies.proto",
+ "src/protozero/test/example_proto/test_messages.proto",
+ "src/protozero/test/example_proto/upper_import.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/ --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/protozero/test/example_proto/library.gen.h",
+ "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.gen.h",
+ "external/perfetto/src/protozero/test/example_proto/test_messages.gen.h",
+ "external/perfetto/src/protozero/test/example_proto/upper_import.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
],
}
@@ -4512,6 +4557,7 @@
"src/protozero/proto_decoder_unittest.cc",
"src/protozero/proto_utils_unittest.cc",
"src/protozero/scattered_stream_writer_unittest.cc",
+ "src/protozero/test/cppgen_conformance_unittest.cc",
"src/protozero/test/fake_scattered_buffer.cc",
"src/protozero/test/protozero_conformance_unittest.cc",
],
@@ -4682,6 +4728,7 @@
name: "perfetto_src_trace_processor_unittests",
srcs: [
"src/trace_processor/args_table_unittest.cc",
+ "src/trace_processor/basic_types_unittest.cc",
"src/trace_processor/clock_tracker_unittest.cc",
"src/trace_processor/event_tracker_unittest.cc",
"src/trace_processor/filtered_row_index_unittest.cc",
@@ -5366,7 +5413,8 @@
":perfetto_protos_perfetto_config_sys_stats_zero_gen",
":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_zero_gen",
":perfetto_protos_perfetto_metrics_android_zero_gen",
":perfetto_protos_perfetto_metrics_zero_gen",
":perfetto_protos_perfetto_trace_android_lite_gen",
@@ -5398,7 +5446,6 @@
":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_track_event_lite_gen",
":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_src_android_internal_headers",
":perfetto_src_android_internal_lazy_library_loader",
":perfetto_src_base_base",
@@ -5421,6 +5468,7 @@
":perfetto_src_profiling_memory_unittests",
":perfetto_src_profiling_memory_wire_protocol",
":perfetto_src_protozero_protozero",
+ ":perfetto_src_protozero_testing_messages_cpp_gen",
":perfetto_src_protozero_testing_messages_lite_gen",
":perfetto_src_protozero_testing_messages_zero_gen",
":perfetto_src_protozero_unittests",
@@ -5511,7 +5559,8 @@
"perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_zero_gen_headers",
"perfetto_protos_perfetto_metrics_android_zero_gen_headers",
"perfetto_protos_perfetto_metrics_zero_gen_headers",
"perfetto_protos_perfetto_trace_android_lite_gen_headers",
@@ -5543,9 +5592,9 @@
"perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
"perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
"perfetto_src_ipc_test_messages_gen_headers",
"perfetto_src_perfetto_cmd_protos_gen_headers",
+ "perfetto_src_protozero_testing_messages_cpp_gen_headers",
"perfetto_src_protozero_testing_messages_lite_gen_headers",
"perfetto_src_protozero_testing_messages_zero_gen_headers",
"perfetto_src_traced_probes_ftrace_test_messages_lite_gen_headers",
@@ -5933,14 +5982,14 @@
":perfetto_protos_perfetto_config_sys_stats_zero_gen",
":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_zero_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_lite_gen",
":perfetto_protos_perfetto_trace_minimal_zero_gen",
":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
":perfetto_protos_perfetto_trace_perfetto_zero_gen",
@@ -5949,7 +5998,6 @@
":perfetto_protos_perfetto_trace_ps_zero_gen",
":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_protos_perfetto_trace_trusted_lite_gen",
":perfetto_src_base_base",
":perfetto_src_base_unix_socket",
":perfetto_src_ipc_ipc",
@@ -5998,14 +6046,14 @@
"perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_zero_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
"perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
"perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
"perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
@@ -6014,7 +6062,6 @@
"perfetto_protos_perfetto_trace_ps_zero_gen_headers",
"perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
"perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
"perfetto_src_perfetto_cmd_protos_gen_headers",
],
defaults: [
diff --git a/BUILD b/BUILD
index 57831e6..9764754 100644
--- a/BUILD
+++ b/BUILD
@@ -66,7 +66,8 @@
":include_perfetto_ext_ipc_ipc",
],
deps = [
- ":protos_perfetto_ipc_wire_protocol",
+ ":protos_perfetto_ipc_wire_protocol_cpp",
+ ":protos_perfetto_ipc_wire_protocol_zero",
] + PERFETTO_CONFIG.deps.protobuf_lite,
)
@@ -182,14 +183,14 @@
":protos_perfetto_config_sys_stats_zero",
":protos_perfetto_config_zero",
":protos_perfetto_ipc_ipc",
- ":protos_perfetto_ipc_wire_protocol",
+ ":protos_perfetto_ipc_wire_protocol_cpp",
+ ":protos_perfetto_ipc_wire_protocol_zero",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
":protos_perfetto_trace_interned_data_zero",
- ":protos_perfetto_trace_minimal_lite",
":protos_perfetto_trace_minimal_zero",
":protos_perfetto_trace_non_minimal_zero",
":protos_perfetto_trace_perfetto_zero",
@@ -198,7 +199,6 @@
":protos_perfetto_trace_ps_zero",
":protos_perfetto_trace_sys_stats_zero",
":protos_perfetto_trace_track_event_zero",
- ":protos_perfetto_trace_trusted_lite",
] + PERFETTO_CONFIG.deps.protobuf_lite,
)
@@ -354,6 +354,7 @@
"include/perfetto/protozero/scattered_heap_buffer.h",
"include/perfetto/protozero/scattered_stream_null_delegate.h",
"include/perfetto/protozero/scattered_stream_writer.h",
+ "include/perfetto/protozero/static_buffer.h",
],
)
@@ -528,6 +529,7 @@
filegroup(
name = "src_protozero_protozero",
srcs = [
+ "src/protozero/field.cc",
"src/protozero/message.cc",
"src/protozero/message_handle.cc",
"src/protozero/packed_repeated_fields.cc",
@@ -535,6 +537,7 @@
"src/protozero/scattered_heap_buffer.cc",
"src/protozero/scattered_stream_null_delegate.cc",
"src/protozero/scattered_stream_writer.cc",
+ "src/protozero/static_buffer.cc",
],
)
@@ -569,7 +572,6 @@
"src/trace_processor/metrics/android/android_mem_unagg.sql",
"src/trace_processor/metrics/android/android_package_list.sql",
"src/trace_processor/metrics/android/android_powrails.sql",
- "src/trace_processor/metrics/android/android_process_growth.sql",
"src/trace_processor/metrics/android/android_startup.sql",
"src/trace_processor/metrics/android/android_startup_cpu.sql",
"src/trace_processor/metrics/android/android_startup_launches.sql",
@@ -578,6 +580,7 @@
"src/trace_processor/metrics/android/java_heap_stats.sql",
"src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql",
"src/trace_processor/metrics/android/process_mem.sql",
+ "src/trace_processor/metrics/android/process_metadata.sql",
"src/trace_processor/metrics/android/process_unagg_mem_view.sql",
"src/trace_processor/metrics/android/span_view_stats.sql",
"src/trace_processor/metrics/android/unsymbolized_frames.sql",
@@ -1156,7 +1159,7 @@
name = "protos_perfetto_common_cpp",
deps = [
":protos_perfetto_common_protos",
- ":protos_perfetto_common_lite",
+ ":protos_perfetto_common_zero",
],
)
@@ -1198,8 +1201,8 @@
name = "protos_perfetto_config_android_cpp",
deps = [
":protos_perfetto_config_android_protos",
- ":protos_perfetto_common_lite",
- ":protos_perfetto_config_android_lite",
+ ":protos_perfetto_config_android_zero",
+ ":protos_perfetto_common_zero",
":protos_perfetto_common_cpp",
],
)
@@ -1237,23 +1240,23 @@
name = "protos_perfetto_config_cpp",
deps = [
":protos_perfetto_config_protos",
- ":protos_perfetto_config_inode_file_cpp",
+ ":protos_perfetto_config_gpu_zero",
+ ":protos_perfetto_config_profiling_zero",
":protos_perfetto_config_android_cpp",
- ":protos_perfetto_config_lite",
- ":protos_perfetto_config_android_lite",
+ ":protos_perfetto_config_sys_stats_zero",
":protos_perfetto_common_cpp",
- ":protos_perfetto_config_gpu_lite",
- ":protos_perfetto_common_lite",
- ":protos_perfetto_config_profiling_lite",
":protos_perfetto_config_process_stats_cpp",
+ ":protos_perfetto_config_power_zero",
+ ":protos_perfetto_config_ftrace_zero",
":protos_perfetto_config_power_cpp",
- ":protos_perfetto_config_process_stats_lite",
- ":protos_perfetto_config_power_lite",
+ ":protos_perfetto_config_inode_file_cpp",
+ ":protos_perfetto_config_zero",
":protos_perfetto_config_profiling_cpp",
- ":protos_perfetto_config_inode_file_lite",
":protos_perfetto_config_gpu_cpp",
- ":protos_perfetto_config_ftrace_lite",
- ":protos_perfetto_config_sys_stats_lite",
+ ":protos_perfetto_config_inode_file_zero",
+ ":protos_perfetto_config_android_zero",
+ ":protos_perfetto_config_process_stats_zero",
+ ":protos_perfetto_common_zero",
":protos_perfetto_config_ftrace_cpp",
":protos_perfetto_config_sys_stats_cpp",
],
@@ -1264,7 +1267,7 @@
name = "protos_perfetto_config_ftrace_cpp",
deps = [
":protos_perfetto_config_ftrace_protos",
- ":protos_perfetto_config_ftrace_lite",
+ ":protos_perfetto_config_ftrace_zero",
],
)
@@ -1297,7 +1300,7 @@
name = "protos_perfetto_config_gpu_cpp",
deps = [
":protos_perfetto_config_gpu_protos",
- ":protos_perfetto_config_gpu_lite",
+ ":protos_perfetto_config_gpu_zero",
],
)
@@ -1330,7 +1333,7 @@
name = "protos_perfetto_config_inode_file_cpp",
deps = [
":protos_perfetto_config_inode_file_protos",
- ":protos_perfetto_config_inode_file_lite",
+ ":protos_perfetto_config_inode_file_zero",
],
)
@@ -1390,7 +1393,7 @@
name = "protos_perfetto_config_power_cpp",
deps = [
":protos_perfetto_config_power_protos",
- ":protos_perfetto_config_power_lite",
+ ":protos_perfetto_config_power_zero",
],
)
@@ -1423,7 +1426,7 @@
name = "protos_perfetto_config_process_stats_cpp",
deps = [
":protos_perfetto_config_process_stats_protos",
- ":protos_perfetto_config_process_stats_lite",
+ ":protos_perfetto_config_process_stats_zero",
],
)
@@ -1456,7 +1459,7 @@
name = "protos_perfetto_config_profiling_cpp",
deps = [
":protos_perfetto_config_profiling_protos",
- ":protos_perfetto_config_profiling_lite",
+ ":protos_perfetto_config_profiling_zero",
],
)
@@ -1512,8 +1515,8 @@
name = "protos_perfetto_config_sys_stats_cpp",
deps = [
":protos_perfetto_config_sys_stats_protos",
- ":protos_perfetto_common_lite",
- ":protos_perfetto_config_sys_stats_lite",
+ ":protos_perfetto_config_sys_stats_zero",
+ ":protos_perfetto_common_zero",
":protos_perfetto_common_cpp",
],
)
@@ -1580,18 +1583,20 @@
":protos_perfetto_config_protos",
":protos_perfetto_config_sys_stats_protos",
":protos_perfetto_ipc_wire_protocol_protos",
- ],
-)
-
-# GN target: //protos/perfetto/ipc:wire_protocol
-perfetto_cc_proto_library(
- name = "protos_perfetto_ipc_wire_protocol",
- deps = [
":protos_perfetto_ipc_wire_protocol_protos",
],
)
-# GN target: //protos/perfetto/ipc:wire_protocol
+# GN target: //protos/perfetto/ipc:wire_protocol_cpp
+perfetto_cc_protocpp_library(
+ name = "protos_perfetto_ipc_wire_protocol_cpp",
+ deps = [
+ ":protos_perfetto_ipc_wire_protocol_protos",
+ ":protos_perfetto_ipc_wire_protocol_zero",
+ ],
+)
+
+# GN target: //protos/perfetto/ipc:wire_protocol_zero
perfetto_proto_library(
name = "protos_perfetto_ipc_wire_protocol_protos",
srcs = [
@@ -1599,6 +1604,14 @@
],
)
+# GN target: //protos/perfetto/ipc:wire_protocol_zero
+perfetto_cc_protozero_library(
+ name = "protos_perfetto_ipc_wire_protocol_zero",
+ deps = [
+ ":protos_perfetto_ipc_wire_protocol_protos",
+ ],
+)
+
# GN target: //protos/perfetto/metrics/android:lite
perfetto_cc_proto_library(
name = "protos_perfetto_metrics_android_lite",
@@ -1621,7 +1634,7 @@
"protos/perfetto/metrics/android/mem_unagg_metric.proto",
"protos/perfetto/metrics/android/package_list.proto",
"protos/perfetto/metrics/android/powrails_metric.proto",
- "protos/perfetto/metrics/android/process_growth.proto",
+ "protos/perfetto/metrics/android/process_metadata.proto",
"protos/perfetto/metrics/android/startup_metric.proto",
"protos/perfetto/metrics/android/unsymbolized_frames.proto",
],
@@ -2154,35 +2167,6 @@
],
)
-# GN target: //protos/perfetto/trace:trusted_lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_trusted_lite",
- deps = [
- ":protos_perfetto_trace_trusted_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace:trusted_lite
-perfetto_proto_library(
- name = "protos_perfetto_trace_trusted_protos",
- srcs = [
- "protos/perfetto/trace/trusted_packet.proto",
- ],
- deps = [
- ":protos_perfetto_common_protos",
- ":protos_perfetto_config_android_protos",
- ":protos_perfetto_config_ftrace_protos",
- ":protos_perfetto_config_gpu_protos",
- ":protos_perfetto_config_inode_file_protos",
- ":protos_perfetto_config_power_protos",
- ":protos_perfetto_config_process_stats_protos",
- ":protos_perfetto_config_profiling_protos",
- ":protos_perfetto_config_protos",
- ":protos_perfetto_config_sys_stats_protos",
- ":protos_perfetto_trace_minimal_protos",
- ],
-)
-
# GN target: //protos/third_party/pprof:lite
perfetto_cc_proto_library(
name = "protos_third_party_pprof_lite",
@@ -2279,14 +2263,14 @@
":protos_perfetto_config_sys_stats_zero",
":protos_perfetto_config_zero",
":protos_perfetto_ipc_ipc",
- ":protos_perfetto_ipc_wire_protocol",
+ ":protos_perfetto_ipc_wire_protocol_cpp",
+ ":protos_perfetto_ipc_wire_protocol_zero",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
":protos_perfetto_trace_interned_data_zero",
- ":protos_perfetto_trace_minimal_lite",
":protos_perfetto_trace_minimal_zero",
":protos_perfetto_trace_non_minimal_zero",
":protos_perfetto_trace_perfetto_zero",
@@ -2295,7 +2279,6 @@
":protos_perfetto_trace_ps_zero",
":protos_perfetto_trace_sys_stats_zero",
":protos_perfetto_trace_track_event_zero",
- ":protos_perfetto_trace_trusted_lite",
] + PERFETTO_CONFIG.deps.protobuf_lite,
)
@@ -2360,14 +2343,14 @@
":protos_perfetto_config_sys_stats_zero",
":protos_perfetto_config_zero",
":protos_perfetto_ipc_ipc",
- ":protos_perfetto_ipc_wire_protocol",
+ ":protos_perfetto_ipc_wire_protocol_cpp",
+ ":protos_perfetto_ipc_wire_protocol_zero",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
":protos_perfetto_trace_interned_data_zero",
- ":protos_perfetto_trace_minimal_lite",
":protos_perfetto_trace_minimal_zero",
":protos_perfetto_trace_non_minimal_zero",
":protos_perfetto_trace_perfetto_zero",
@@ -2376,7 +2359,6 @@
":protos_perfetto_trace_ps_zero",
":protos_perfetto_trace_sys_stats_zero",
":protos_perfetto_trace_track_event_zero",
- ":protos_perfetto_trace_trusted_lite",
":src_perfetto_cmd_protos",
] + PERFETTO_CONFIG.deps.protobuf_lite +
PERFETTO_CONFIG.deps.zlib,
diff --git a/docs/security-model.md b/docs/security-model.md
index bff44a9..369e6cc 100644
--- a/docs/security-model.md
+++ b/docs/security-model.md
@@ -51,10 +51,9 @@
untrusted-and-unprivileged and trusted-and-more-privileged entities).
**Attestation of trace contents**
-The tracing service guarantees that the `TracePacket` fields defined also in
-[trusted_packet.proto](/protos/perfetto/trace/trusted_packet.proto) cannot be
-spoofed by the Producer(s). Packets that try to define those fields are rejected
-(modulo the clock snapshots).
+The tracing service guarantees that the `TracePacket` fields written by the
+Service cannot be spoofed by the Producer(s).
+Packets that try to define those fields are rejected, modulo clock snapshots.
See [PacketStreamValidator](/src/tracing/core/packet_stream_validator.cc) and
[its unit test](/src/tracing/core/packet_stream_validator_unittest.cc) for more
details.
diff --git a/docs/trace-format.md b/docs/trace-format.md
index ca5db49..ec6c3eb 100644
--- a/docs/trace-format.md
+++ b/docs/trace-format.md
@@ -9,9 +9,9 @@
(see [trace_packet.proto](/protos/perfetto/trace/trace_packet.proto)).
As a key part of the Perfetto design, the tracing service is agnostic of the
-content of TracePacket, modulo the few fields defined in
-[trusted_packet.proto](/protos/perfetto/trace/trusted_packet.proto) that are
-produced by the service itself.
+content of TracePacket, modulo few fields (e.g., `trusted_packed_*`,
+clock snapshots, copy of the original config) that are produced by the service
+itself.
Each data source can extend the trace with their app-specific protobuf schema.
*** aside
diff --git a/gn/proto_library.gni b/gn/proto_library.gni
index c7af114..3e96c4d 100644
--- a/gn/proto_library.gni
+++ b/gn/proto_library.gni
@@ -182,11 +182,11 @@
forward_variables_from(invoker, vars_to_forward)
}
} else if (gen_type == "cpp") {
- lite_target_name_ = string_replace(target_name, expansion_token, "lite")
+ zero_target_name_ = string_replace(target_name, expansion_token, "zero")
protozero_cpp_library(target_name_) {
proto_in_dir = proto_path
proto_out_dir = proto_path
- deps = deps_ + [ ":$lite_target_name_" ]
+ deps = deps_ + [ ":$zero_target_name_" ]
forward_variables_from(invoker, vars_to_forward)
}
} else if (gen_type == "lite") {
diff --git a/gn/standalone/toolchain/BUILD.gn b/gn/standalone/toolchain/BUILD.gn
index 7394802..4f38ceb 100644
--- a/gn/standalone/toolchain/BUILD.gn
+++ b/gn/standalone/toolchain/BUILD.gn
@@ -179,7 +179,7 @@
command = "rm -f {{output}} && libtool -static {{arflags}} -o {{output}} -filelist $rspfile"
} else {
rspfile_content = "{{inputs}}"
- command = "$ar rcsD {{output}} @$rspfile"
+ command = "rm -f {{output}} && $ar rcsD {{output}} @$rspfile"
}
outputs = [
"{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
diff --git a/include/perfetto/base/compiler.h b/include/perfetto/base/compiler.h
index 0b2efbf..0f08b42 100644
--- a/include/perfetto/base/compiler.h
+++ b/include/perfetto/base/compiler.h
@@ -38,25 +38,6 @@
#define PERFETTO_NO_INLINE
#endif
-// TODO(lalitm): is_trivially_constructible is currently not available
-// in some environments we build in. Reenable when that environment supports
-// this.
-#if defined(__GLIBCXX__)
-#define PERFETTO_IS_TRIVIALLY_CONSTRUCTIBLE(T) true
-#else
-#define PERFETTO_IS_TRIVIALLY_CONSTRUCTIBLE(T) \
- std::is_trivially_constructible<T>::value
-#endif
-
-// TODO(lalitm): is_trivially_copyable is currently not available
-// in some environments we build in. Reenable when that environment supports
-// this.
-#if defined(__GLIBCXX__)
-#define PERFETTO_IS_TRIVIALLY_COPYABLE(T) true
-#else
-#define PERFETTO_IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable<T>::value
-#endif
-
#if defined(__GNUC__) || defined(__clang__)
#define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() __PRETTY_FUNCTION__
#elif defined(_MSC_VER)
diff --git a/include/perfetto/protozero/BUILD.gn b/include/perfetto/protozero/BUILD.gn
index 994ff60..7afe1b9 100644
--- a/include/perfetto/protozero/BUILD.gn
+++ b/include/perfetto/protozero/BUILD.gn
@@ -28,5 +28,6 @@
"scattered_heap_buffer.h",
"scattered_stream_null_delegate.h",
"scattered_stream_writer.h",
+ "static_buffer.h",
]
}
diff --git a/include/perfetto/protozero/field.h b/include/perfetto/protozero/field.h
index f76fe84..69b2a15 100644
--- a/include/perfetto/protozero/field.h
+++ b/include/perfetto/protozero/field.h
@@ -182,6 +182,10 @@
*val = static_cast<T>(as_int32());
}
+ // Serializes the field back into a proto-encoded byte stream and appends it
+ // to |dst|. |dst| is resized accordingly.
+ void SerializeAndAppendTo(std::string* dst);
+
private:
// Fields are deliberately not initialized to keep the class trivially
// constructible. It makes a large perf difference for ProtoDecoder.
diff --git a/include/perfetto/protozero/message.h b/include/perfetto/protozero/message.h
index 213a436..c3fdfd6 100644
--- a/include/perfetto/protozero/message.h
+++ b/include/perfetto/protozero/message.h
@@ -171,6 +171,16 @@
ScatteredStreamWriter* stream_writer_for_testing() { return stream_writer_; }
+ // Appends some raw bytes to the message. The use-case for this is preserving
+ // unknown fields in the decode -> re-encode path of xxx.gen.cc classes
+ // generated by the cppgen_plugin.cc.
+ // The caller needs to guarantee that the appended data is properly
+ // proto-encoded and each field has a proto preamble.
+ void AppendRawProtoBytes(const void* data, size_t size) {
+ const uint8_t* src = reinterpret_cast<const uint8_t*>(data);
+ WriteToStream(src, src + size);
+ }
+
private:
Message(const Message&) = delete;
Message& operator=(const Message&) = delete;
diff --git a/include/perfetto/protozero/proto_decoder.h b/include/perfetto/protozero/proto_decoder.h
index 5794cc9..b58e64e 100644
--- a/include/perfetto/protozero/proto_decoder.h
+++ b/include/perfetto/protozero/proto_decoder.h
@@ -332,7 +332,7 @@
// implicit initializers on all the ~1000 entries. We need it to initialize
// only on the first |max_field_id| fields, the remaining capacity doesn't
// require initialization.
- static_assert(PERFETTO_IS_TRIVIALLY_CONSTRUCTIBLE(Field) &&
+ static_assert(std::is_trivially_constructible<Field>::value &&
std::is_trivially_destructible<Field>::value &&
std::is_trivial<Field>::value,
"Field must be a trivial aggregate type");
diff --git a/include/perfetto/protozero/proto_utils.h b/include/perfetto/protozero/proto_utils.h
index 8a93951..d8f0592 100644
--- a/include/perfetto/protozero/proto_utils.h
+++ b/include/perfetto/protozero/proto_utils.h
@@ -225,20 +225,22 @@
// buffer.
inline const uint8_t* ParseVarInt(const uint8_t* start,
const uint8_t* end,
- uint64_t* value) {
+ uint64_t* out_value) {
const uint8_t* pos = start;
- uint64_t shift = 0;
- *value = 0;
- do {
- if (PERFETTO_UNLIKELY(pos >= end)) {
- *value = 0;
- return start;
+ uint64_t value = 0;
+ for (uint32_t shift = 0; pos < end && shift < 64u; shift += 7) {
+ // Cache *pos into |cur_byte| to prevent that the compiler dereferences the
+ // pointer twice (here and in the if() below) due to char* aliasing rules.
+ uint8_t cur_byte = *pos++;
+ value |= static_cast<uint64_t>(cur_byte & 0x7f) << shift;
+ if ((cur_byte & 0x80) == 0) {
+ // In valid cases we get here.
+ *out_value = value;
+ return pos;
}
- PERFETTO_DCHECK(shift < 64ull);
- *value |= static_cast<uint64_t>(*pos & 0x7f) << shift;
- shift += 7;
- } while (*pos++ & 0x80);
- return pos;
+ }
+ *out_value = 0;
+ return start;
}
} // namespace proto_utils
diff --git a/include/perfetto/protozero/static_buffer.h b/include/perfetto/protozero/static_buffer.h
new file mode 100644
index 0000000..6f5924f
--- /dev/null
+++ b/include/perfetto/protozero/static_buffer.h
@@ -0,0 +1,101 @@
+/*
+ * 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 INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "perfetto/base/export.h"
+#include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace protozero {
+
+class Message;
+
+// A simple implementation of ScatteredStreamWriter::Delegate backed by a
+// fixed-size buffer. It doesn't support expansion. The caller needs to ensure
+// to never write more than the size of the buffer. Will CHECK() otherwise.
+class PERFETTO_EXPORT StaticBufferDelegate
+ : public ScatteredStreamWriter::Delegate {
+ public:
+ StaticBufferDelegate(uint8_t* buf, size_t len) : range_{buf, buf + len} {}
+ ~StaticBufferDelegate() override;
+
+ // ScatteredStreamWriter::Delegate implementation.
+ ContiguousMemoryRange GetNewBuffer() override;
+
+ ContiguousMemoryRange const range_;
+ bool get_new_buffer_called_once_ = false;
+};
+
+// Helper function to create protozero messages backed by a fixed-size buffer
+// in one line. You can write:
+// protozero::Static<protozero::MyMessage> msg(buf.data(), buf.size());
+// msg->set_stuff(...);
+// size_t bytes_encoded = msg.Finalize();
+template <typename T /* protozero::Message */>
+class StaticBuffered {
+ public:
+ StaticBuffered(void* buf, size_t len)
+ : delegate_(reinterpret_cast<uint8_t*>(buf), len), writer_(&delegate_) {
+ msg_.Reset(&writer_);
+ }
+
+ // This can't be neither copied nor moved because Message hands out pointers
+ // to itself when creating submessages.
+ StaticBuffered(const StaticBuffered&) = delete;
+ StaticBuffered& operator=(const StaticBuffered&) = delete;
+ StaticBuffered(StaticBuffered&&) = delete;
+ StaticBuffered& operator=(StaticBuffered&&) = delete;
+
+ T* get() { return &msg_; }
+ T* operator->() { return &msg_; }
+
+ // The lack of a size() method is deliberate. It's to prevent that one
+ // accidentally calls size() before Finalize().
+
+ // Returns the number of encoded bytes (<= the size passed in the ctor).
+ size_t Finalize() {
+ msg_.Finalize();
+ return static_cast<size_t>(writer_.write_ptr() - delegate_.range_.begin);
+ }
+
+ private:
+ StaticBufferDelegate delegate_;
+ ScatteredStreamWriter writer_;
+ T msg_;
+};
+
+// Helper function to create stack-based protozero messages in one line.
+// You can write:
+// protozero::StackBuffered<protozero::MyMessage, 16> msg;
+// msg->set_stuff(...);
+// size_t bytes_encoded = msg.Finalize();
+template <typename T /* protozero::Message */, size_t N>
+class StackBuffered : public StaticBuffered<T> {
+ public:
+ StackBuffered() : StaticBuffered<T>(&buf_[0], N) {}
+
+ private:
+ uint8_t buf_[N]; // Deliberately not initialized.
+};
+
+} // namespace protozero
+
+#endif // INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
diff --git a/include/perfetto/trace_processor/basic_types.h b/include/perfetto/trace_processor/basic_types.h
index efac31c..ca540d2 100644
--- a/include/perfetto/trace_processor/basic_types.h
+++ b/include/perfetto/trace_processor/basic_types.h
@@ -57,6 +57,13 @@
return value;
}
+ static SqlValue Double(double v) {
+ SqlValue value;
+ value.double_value = v;
+ value.type = Type::kDouble;
+ return value;
+ }
+
static SqlValue String(const char* v) {
SqlValue value;
value.string_value = v;
@@ -69,7 +76,7 @@
return double_value;
}
- int Compare(const SqlValue& value) const {
+ int64_t Compare(const SqlValue& value) const {
// TODO(lalitm): this is almost the same as what SQLite does with the
// exception of comparisions between long and double - we choose (for
// performance reasons) to omit comparisions between them.
@@ -80,10 +87,11 @@
case Type::kNull:
return 0;
case Type::kLong:
- return static_cast<int>(long_value - value.long_value);
+ return long_value - value.long_value;
case Type::kDouble: {
- double diff = double_value - value.double_value;
- return diff < 0 ? -1 : (diff > 0 ? 1 : 0);
+ return double_value < value.double_value
+ ? -1
+ : (double_value > value.double_value ? 1 : 0);
}
case Type::kString:
return strcmp(string_value, value.string_value);
@@ -92,7 +100,7 @@
int ret = memcmp(bytes_value, value.bytes_value, bytes);
if (ret != 0)
return ret;
- return static_cast<int>(bytes_count - value.bytes_count);
+ return static_cast<int64_t>(bytes_count - value.bytes_count);
}
}
PERFETTO_FATAL("For GCC");
diff --git a/protos/perfetto/ipc/BUILD.gn b/protos/perfetto/ipc/BUILD.gn
index 48f54a1..c65b9f4 100644
--- a/protos/perfetto/ipc/BUILD.gn
+++ b/protos/perfetto/ipc/BUILD.gn
@@ -30,8 +30,11 @@
]
}
-perfetto_proto_library("wire_protocol") {
- proto_generators = [ "lite" ]
+perfetto_proto_library("wire_protocol_@TYPE@") {
+ proto_generators = [
+ "zero",
+ "cpp",
+ ]
sources = [
"wire_protocol.proto",
]
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index 41353b0..3f8571c 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -26,7 +26,7 @@
"mem_unagg_metric.proto",
"package_list.proto",
"powrails_metric.proto",
- "process_growth.proto",
+ "process_metadata.proto",
"startup_metric.proto",
"unsymbolized_frames.proto",
]
diff --git a/protos/perfetto/metrics/android/heap_profile_callsites.proto b/protos/perfetto/metrics/android/heap_profile_callsites.proto
index d19bba3..df1a516 100644
--- a/protos/perfetto/metrics/android/heap_profile_callsites.proto
+++ b/protos/perfetto/metrics/android/heap_profile_callsites.proto
@@ -18,6 +18,8 @@
package perfetto.protos;
+import "protos/perfetto/metrics/android/process_metadata.proto";
+
message HeapProfileCallsites {
message Frame {
optional string name = 1;
@@ -51,10 +53,12 @@
}
// Callsites per process instance.
- // Next id: 6
+ // Next id: 7
message InstanceStats {
optional uint32 pid = 1;
+ // TODO(ilkos): Remove process_name in favour of the metadata.
optional string process_name = 2;
+ optional AndroidProcessMetadata process = 6;
repeated Callsite callsites = 3;
// Bytes allocated via malloc but not freed.
diff --git a/protos/perfetto/metrics/android/java_heap_stats.proto b/protos/perfetto/metrics/android/java_heap_stats.proto
index a5e1513..e07190b 100644
--- a/protos/perfetto/metrics/android/java_heap_stats.proto
+++ b/protos/perfetto/metrics/android/java_heap_stats.proto
@@ -18,6 +18,8 @@
package perfetto.protos;
+import "protos/perfetto/metrics/android/process_metadata.proto";
+
message JavaHeapStats {
message Sample {
optional int64 ts = 1;
@@ -29,7 +31,7 @@
// dump is enabled).
message InstanceStats {
optional uint32 upid = 1;
- optional string process_name = 2;
+ optional AndroidProcessMetadata process = 2;
repeated Sample samples = 3;
}
diff --git a/protos/perfetto/metrics/android/process_growth.proto b/protos/perfetto/metrics/android/process_growth.proto
deleted file mode 100644
index 50fcec5..0000000
--- a/protos/perfetto/metrics/android/process_growth.proto
+++ /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.
- */
-syntax = "proto2";
-option optimize_for = LITE_RUNTIME;
-
-package perfetto.protos;
-
-message AndroidProcessGrowth {
- // Next id: 7
- message InstanceMetrics {
- optional uint32 pid = 1;
- optional string process_name = 2;
-
- optional int64 anon_and_swap_start_value = 5;
- optional int64 anon_and_swap_change_bytes = 3;
-
- // Bytes allocated via malloc but not freed.
- // Only applicable with a heap profile.
- optional int64 malloc_memory_change_bytes = 4;
- // Total bytes allocated via malloc. Only applicable with a heap profile.
- optional int64 malloc_memory_total_allocated_bytes = 6;
- }
-
- // Process memory per process instance.
- repeated InstanceMetrics instance_metrics = 1;
-}
diff --git a/protos/perfetto/metrics/android/process_metadata.proto b/protos/perfetto/metrics/android/process_metadata.proto
new file mode 100644
index 0000000..9c35812
--- /dev/null
+++ b/protos/perfetto/metrics/android/process_metadata.proto
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+
+package perfetto.protos;
+
+message AndroidProcessMetadata {
+ optional string name = 1;
+ optional int64 uid = 2;
+ optional string package_name = 3;
+ optional int64 apk_version_code = 4;
+ optional bool debuggable = 5;
+}
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index 508e830..6225559 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -23,7 +23,6 @@
import "protos/perfetto/metrics/android/cpu_metric.proto";
import "protos/perfetto/metrics/android/mem_metric.proto";
import "protos/perfetto/metrics/android/mem_unagg_metric.proto";
-import "protos/perfetto/metrics/android/process_growth.proto";
import "protos/perfetto/metrics/android/ion_metric.proto";
import "protos/perfetto/metrics/android/lmk_metric.proto";
import "protos/perfetto/metrics/android/powrails_metric.proto";
@@ -51,7 +50,7 @@
//
// Next id: 18
message TraceMetrics {
- reserved 4, 13, 14;
+ reserved 4, 10, 13, 14;
// Battery counters metric on Android.
optional AndroidBatteryMetric android_batt = 5;
@@ -71,9 +70,6 @@
// Package list.
optional AndroidPackageList android_package_list = 12;
- // Per-process memory growth metrics.
- optional AndroidProcessGrowth android_process_growth = 10;
-
// ion buffer memory metrics.
optional AndroidIonMetric android_ion = 9;
diff --git a/protos/perfetto/trace/BUILD.gn b/protos/perfetto/trace/BUILD.gn
index ca76396..bc312e0 100644
--- a/protos/perfetto/trace/BUILD.gn
+++ b/protos/perfetto/trace/BUILD.gn
@@ -39,9 +39,6 @@
"system_info.proto",
]
-# Used only for packet_stream_validator.cc (in the service).
-proto_sources_trusted = [ "trusted_packet.proto" ]
-
# Most targets should either depend on :zero (writers) / :lite (readers)
# or ":minimal_zero" / :minimal_lite (mostly for chrome).
@@ -95,17 +92,6 @@
sources = proto_sources_minimal
}
-# Used by the traced service for packet sanitization.
-perfetto_proto_library("trusted_@TYPE@") {
- proto_generators = [ "lite" ]
- deps = [
- ":minimal_@TYPE@",
- "../common:@TYPE@",
- "../config:@TYPE@",
- ]
- sources = proto_sources_trusted
-}
-
# This target is not used in the tree and is built only to guarantee that the
# autogenerated merged proto has a valid syntax.
perfetto_proto_library("merged_trace") {
diff --git a/protos/perfetto/trace/clock_snapshot.proto b/protos/perfetto/trace/clock_snapshot.proto
index 12ce1b6..e3dff0f 100644
--- a/protos/perfetto/trace/clock_snapshot.proto
+++ b/protos/perfetto/trace/clock_snapshot.proto
@@ -45,22 +45,23 @@
// IDs and setting this ID to hash(full_clock_name) & ~127.
optional uint32 clock_id = 1;
- // Unit is ns unless specified otherwise by the resolution_* fields below.
+ // Absolute timestamp. Unit is ns unless specified otherwise by the
+ // unit_multiplier_ns field below.
optional uint64 timestamp = 2;
- // TODO(eseckler): the fields below and sequence-scoped clock IDs are not
- // supported yet by the trace processor.
+ // When true each TracePacket's timestamp should be interpreted as a delta
+ // from the last TracePacket's timestamp (referencing this clock) emitted by
+ // the same packet_sequence_id. Should only be used for user-defined
+ // sequence-local clocks. The first packet timestamp after each
+ // ClockSnapshot that contains this clock is relative to the |timestamp| in
+ // the ClockSnapshot.
+ optional bool is_incremental = 3;
- // When true the timestamp should be interpreted as a delta from the last
- // TracePacket's timestamp emitted by the same packet_sequence_id.
- // The first packet timestamp after a ClockSnapshot is relative to the last
- // ClockSnapshot seen on the packet sequence.
- // optional bool is_incremental = 3;
-
- // Allows to specify a custom unit different than the default (ns)
- // for this clock domain. A multiplier of 1000 means that a timestamp = 3
- // should be interpreted as 3000 ns = 3 us.
- // optional uint64 unit_multiplier_ns = 4;
+ // Allows to specify a custom unit different than the default (ns) for this
+ // clock domain. A multiplier of 1000 means that a timestamp = 3 should be
+ // interpreted as 3000 ns = 3 us. All snapshots for the same clock within a
+ // trace need to use the same unit.
+ optional uint64 unit_multiplier_ns = 4;
}
repeated Clock clocks = 1;
}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index d126980..abfe920 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -758,22 +758,23 @@
// IDs and setting this ID to hash(full_clock_name) & ~127.
optional uint32 clock_id = 1;
- // Unit is ns unless specified otherwise by the resolution_* fields below.
+ // Absolute timestamp. Unit is ns unless specified otherwise by the
+ // unit_multiplier_ns field below.
optional uint64 timestamp = 2;
- // TODO(eseckler): the fields below and sequence-scoped clock IDs are not
- // supported yet by the trace processor.
+ // When true each TracePacket's timestamp should be interpreted as a delta
+ // from the last TracePacket's timestamp (referencing this clock) emitted by
+ // the same packet_sequence_id. Should only be used for user-defined
+ // sequence-local clocks. The first packet timestamp after each
+ // ClockSnapshot that contains this clock is relative to the |timestamp| in
+ // the ClockSnapshot.
+ optional bool is_incremental = 3;
- // When true the timestamp should be interpreted as a delta from the last
- // TracePacket's timestamp emitted by the same packet_sequence_id.
- // The first packet timestamp after a ClockSnapshot is relative to the last
- // ClockSnapshot seen on the packet sequence.
- // optional bool is_incremental = 3;
-
- // Allows to specify a custom unit different than the default (ns)
- // for this clock domain. A multiplier of 1000 means that a timestamp = 3
- // should be interpreted as 3000 ns = 3 us.
- // optional uint64 unit_multiplier_ns = 4;
+ // Allows to specify a custom unit different than the default (ns) for this
+ // clock domain. A multiplier of 1000 means that a timestamp = 3 should be
+ // interpreted as 3000 ns = 3 us. All snapshots for the same clock within a
+ // trace need to use the same unit.
+ optional uint64 unit_multiplier_ns = 4;
}
repeated Clock clocks = 1;
}
@@ -3030,6 +3031,23 @@
// Begin of protos/perfetto/trace/profiling/heap_graph.proto
+message ObfuscatedMember {
+ optional string obfuscated_name = 1;
+ optional string deobfuscated_name = 2;
+}
+
+message ObfuscatedClass {
+ optional string obfuscated_name = 1;
+ optional string deobfuscated_name = 2;
+ repeated ObfuscatedMember obfuscated_members = 3;
+}
+
+message DeobfuscationMapping {
+ optional string package_name = 1;
+ optional int64 version_code = 2;
+ repeated ObfuscatedClass obfusucated_classes = 3;
+}
+
message HeapGraphRoot {
enum Type {
ROOT_UNKNOWN = 0;
@@ -3049,7 +3067,7 @@
ROOT_JNI_MONITOR = 14;
};
// Objects retained by this root.
- repeated uint64 object_ids = 1;
+ repeated uint64 object_ids = 1 [packed = true];
optional Type root_type = 2;
}
@@ -3065,10 +3083,10 @@
// Indices for InternedData.field_names for the name of the field referring
// to the object.
- repeated uint64 reference_field_id = 4;
+ repeated uint64 reference_field_id = 4 [packed = true];
// Ids of the Object that is referred to.
- repeated uint64 reference_object_id = 5;
+ repeated uint64 reference_object_id = 5 [packed = true];
}
message HeapGraph {
diff --git a/protos/perfetto/trace/profiling/heap_graph.proto b/protos/perfetto/trace/profiling/heap_graph.proto
index d29c292..5601b9b 100644
--- a/protos/perfetto/trace/profiling/heap_graph.proto
+++ b/protos/perfetto/trace/profiling/heap_graph.proto
@@ -24,6 +24,23 @@
package perfetto.protos;
+message ObfuscatedMember {
+ optional string obfuscated_name = 1;
+ optional string deobfuscated_name = 2;
+}
+
+message ObfuscatedClass {
+ optional string obfuscated_name = 1;
+ optional string deobfuscated_name = 2;
+ repeated ObfuscatedMember obfuscated_members = 3;
+}
+
+message DeobfuscationMapping {
+ optional string package_name = 1;
+ optional int64 version_code = 2;
+ repeated ObfuscatedClass obfusucated_classes = 3;
+}
+
message HeapGraphRoot {
enum Type {
ROOT_UNKNOWN = 0;
@@ -43,7 +60,7 @@
ROOT_JNI_MONITOR = 14;
};
// Objects retained by this root.
- repeated uint64 object_ids = 1;
+ repeated uint64 object_ids = 1 [packed = true];
optional Type root_type = 2;
}
@@ -59,10 +76,10 @@
// Indices for InternedData.field_names for the name of the field referring
// to the object.
- repeated uint64 reference_field_id = 4;
+ repeated uint64 reference_field_id = 4 [packed = true];
// Ids of the Object that is referred to.
- repeated uint64 reference_object_id = 5;
+ repeated uint64 reference_object_id = 5 [packed = true];
}
message HeapGraph {
diff --git a/protos/perfetto/trace/trusted_packet.proto b/protos/perfetto/trace/trusted_packet.proto
deleted file mode 100644
index 8316994..0000000
--- a/protos/perfetto/trace/trusted_packet.proto
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-// Use proto3 syntax as an optimization. The difference is that proto2 stores
-// unknown fields seen while decoding in an internal buffer (std::string) while
-// proto3 completely drops them. Since during validation we only need to check
-// for the presence of the trusted fields below, we can use proto3 as a way to
-// speed up this process.
-//
-// See https://developers.google.com/protocol-buffers/docs/proto3#unknowns and
-// https://android-review.googlesource.com/c/platform/external/perfetto/+/
-// 591673#17 for details.
-syntax = "proto3";
-option optimize_for = LITE_RUNTIME;
-
-import "protos/perfetto/common/trace_stats.proto";
-import "protos/perfetto/config/trace_config.proto";
-import "protos/perfetto/trace/clock_snapshot.proto";
-import "protos/perfetto/trace/system_info.proto";
-import "protos/perfetto/trace/trigger.proto";
-
-package perfetto.protos;
-
-// This proto contains trusted fields of TracePacket which may only be generated
-// by the service (as opposed to the untrusted producers). Note that the field
-// ids here must be kept in sync with TracePacket.
-// This protobuf serves two purposes:
-// 1. Security validation of packets (see packet_stream_validator.cc)
-// 2. Avoid bloating the service binary with symbols for all possible trace
-// protos. The service doesn't really care about all the protos in the trace,
-// is just passes them through.
-message TrustedPacket {
- // User id of the producer which generated this packet.
- // The oneof boilerplate here is required to tell the difference between
- // uid == 0 and uid not set (the writer uses proto2).
- oneof optional_trusted_uid { int32 trusted_uid = 3; };
-
- oneof optional_trusted_packet_sequence_id {
- uint32 trusted_packet_sequence_id = 10;
- }
-
- ClockSnapshot clock_snapshot = 6;
- uint64 timestamp = 8;
- TraceConfig trace_config = 33;
- TraceStats trace_stats = 35;
- bytes synchronization_marker = 36;
- bool previous_packet_dropped = 42;
- SystemInfo system_info = 45;
- Trigger trigger = 46;
-}
diff --git a/src/ipc/BUILD.gn b/src/ipc/BUILD.gn
index ed0ecd2..bf2b1af 100644
--- a/src/ipc/BUILD.gn
+++ b/src/ipc/BUILD.gn
@@ -31,7 +31,7 @@
deps = [
"../../gn:default_deps",
"../../gn:protobuf_lite",
- "../../protos/perfetto/ipc:wire_protocol",
+ "../../protos/perfetto/ipc:wire_protocol_cpp",
"../base",
]
sources = [
@@ -54,7 +54,7 @@
deps = [
":ipc",
"../../gn:default_deps",
- "../../protos/perfetto/ipc:wire_protocol",
+ "../../protos/perfetto/ipc:wire_protocol_cpp",
]
}
@@ -65,7 +65,7 @@
":test_messages",
"../../gn:default_deps",
"../../gn:gtest_and_gmock",
- "../../protos/perfetto/ipc:wire_protocol",
+ "../../protos/perfetto/ipc:wire_protocol_cpp",
"../base",
"../base:test_support",
]
diff --git a/src/ipc/buffered_frame_deserializer.cc b/src/ipc/buffered_frame_deserializer.cc
index dc107f7..9ef22eb 100644
--- a/src/ipc/buffered_frame_deserializer.cc
+++ b/src/ipc/buffered_frame_deserializer.cc
@@ -25,7 +25,7 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/utils.h"
-#include "protos/perfetto/ipc/wire_protocol.pb.h"
+#include "protos/perfetto/ipc/wire_protocol.gen.h"
namespace perfetto {
namespace ipc {
@@ -166,23 +166,18 @@
if (size == 0)
return;
std::unique_ptr<Frame> frame(new Frame);
- if (frame->ParseFromArray(data, static_cast<int>(size)))
+ if (frame->ParseFromArray(data, size))
decoded_frames_.push_back(std::move(frame));
}
// static
std::string BufferedFrameDeserializer::Serialize(const Frame& frame) {
+ std::vector<uint8_t> payload = frame.SerializeAsArray();
+ const uint32_t payload_size = static_cast<uint32_t>(payload.size());
std::string buf;
- buf.reserve(1024); // Just an educated guess to avoid trivial expansions.
- buf.insert(0, kHeaderSize, 0); // Reserve the space for the header.
- frame.AppendToString(&buf);
- const uint32_t payload_size = static_cast<uint32_t>(buf.size() - kHeaderSize);
- PERFETTO_DCHECK(payload_size == static_cast<uint32_t>(frame.GetCachedSize()));
- // Don't send messages larger than what the receiver can handle.
- PERFETTO_DCHECK(kHeaderSize + payload_size <= kIPCBufferSize);
- char header[kHeaderSize];
- memcpy(header, base::AssumeLittleEndian(&payload_size), kHeaderSize);
- buf.replace(0, kHeaderSize, header, kHeaderSize);
+ buf.resize(kHeaderSize + payload_size);
+ memcpy(&buf[0], base::AssumeLittleEndian(&payload_size), kHeaderSize);
+ memcpy(&buf[kHeaderSize], payload.data(), payload.size());
return buf;
}
diff --git a/src/ipc/buffered_frame_deserializer.h b/src/ipc/buffered_frame_deserializer.h
index 3aeee1f..92988e6 100644
--- a/src/ipc/buffered_frame_deserializer.h
+++ b/src/ipc/buffered_frame_deserializer.h
@@ -31,7 +31,7 @@
namespace perfetto {
namespace ipc {
-class Frame; // Defined in the protobuf autogenerated wire_protocol.pb.h.
+class Frame; // Defined in the protobuf autogenerated wire_protocol.gen.h.
// Deserializes incoming frames, taking care of buffering and tokenization.
// Used by both host and client to decode incoming frames.
diff --git a/src/ipc/buffered_frame_deserializer_unittest.cc b/src/ipc/buffered_frame_deserializer_unittest.cc
index 792365b..9ddf8d8 100644
--- a/src/ipc/buffered_frame_deserializer_unittest.cc
+++ b/src/ipc/buffered_frame_deserializer_unittest.cc
@@ -23,7 +23,7 @@
#include "perfetto/ext/base/utils.h"
#include "test/gtest_and_gmock.h"
-#include "protos/perfetto/ipc/wire_protocol.pb.h"
+#include "protos/perfetto/ipc/wire_protocol.gen.h"
namespace perfetto {
namespace ipc {
@@ -60,15 +60,16 @@
padding_char = padding_char == 'z' ? '0' : padding_char + 1;
padding[i] = padding_char;
}
- frame.add_data_for_testing(padding.data(), padding_size);
+ frame.add_data_for_testing(std::string(padding.data(), padding_size));
}
- PERFETTO_CHECK(frame.ByteSize() == static_cast<int>(payload_size));
+ PERFETTO_CHECK(frame.SerializeAsString().size() == payload_size);
std::vector<char> encoded_frame;
encoded_frame.resize(size);
char* enc_buf = encoded_frame.data();
- PERFETTO_CHECK(frame.SerializeToArray(enc_buf + kHeaderSize,
- static_cast<int>(payload_size)));
+
+ std::string payload = frame.SerializeAsString();
memcpy(enc_buf, base::AssumeLittleEndian(&payload_size), kHeaderSize);
+ memcpy(enc_buf + kHeaderSize, payload.data(), payload.size());
PERFETTO_CHECK(encoded_frame.size() == size);
return encoded_frame;
}
@@ -108,8 +109,7 @@
// Excactly one frame should be decoded, with no leftover buffer.
auto decoded_frame = bfd.PopNextFrame();
ASSERT_TRUE(decoded_frame);
- ASSERT_EQ(static_cast<int32_t>(size - kHeaderSize),
- decoded_frame->ByteSize());
+ ASSERT_EQ(size - kHeaderSize, decoded_frame->SerializeAsString().size());
ASSERT_FALSE(bfd.PopNextFrame());
ASSERT_EQ(0u, bfd.size());
}
@@ -132,11 +132,11 @@
method->set_id(0x424242);
method->set_name("foo");
std::vector<char> serialized_frame;
- uint32_t payload_size = static_cast<uint32_t>(frame.ByteSize());
+ std::string payload = frame.SerializeAsString();
+ uint32_t payload_size = static_cast<uint32_t>(payload.size());
serialized_frame.resize(kHeaderSize + payload_size);
- ASSERT_TRUE(frame.SerializeToArray(serialized_frame.data() + kHeaderSize,
- static_cast<int>(payload_size)));
+ memcpy(serialized_frame.data() + kHeaderSize, payload.data(), payload_size);
memcpy(serialized_frame.data(), base::AssumeLittleEndian(&payload_size),
kHeaderSize);
@@ -163,8 +163,8 @@
// Validate the received frame2.
std::unique_ptr<Frame> decoded_simple_frame = bfd.PopNextFrame();
ASSERT_TRUE(decoded_simple_frame);
- ASSERT_EQ(static_cast<int32_t>(simple_frame.size() - kHeaderSize),
- decoded_simple_frame->ByteSize());
+ ASSERT_EQ(simple_frame.size() - kHeaderSize,
+ decoded_simple_frame->SerializeAsString().size());
std::unique_ptr<Frame> decoded_frame = bfd.PopNextFrame();
ASSERT_TRUE(decoded_frame);
@@ -238,8 +238,7 @@
for (size_t expected_size : batch) {
auto frame = bfd.PopNextFrame();
ASSERT_TRUE(frame);
- ASSERT_EQ(static_cast<int32_t>(expected_size - kHeaderSize),
- frame->ByteSize());
+ ASSERT_EQ(expected_size - kHeaderSize, frame->SerializeAsString().size());
}
ASSERT_FALSE(bfd.PopNextFrame());
ASSERT_EQ(0u, bfd.size());
@@ -301,8 +300,7 @@
ASSERT_FALSE(decoded_frame);
} else {
ASSERT_TRUE(decoded_frame);
- ASSERT_EQ(static_cast<int32_t>(size - kHeaderSize),
- decoded_frame->ByteSize());
+ ASSERT_EQ(size - kHeaderSize, decoded_frame->SerializeAsString().size());
}
ASSERT_EQ(0u, bfd.size());
}
diff --git a/src/ipc/client_impl.h b/src/ipc/client_impl.h
index 71c211f..35dea50 100644
--- a/src/ipc/client_impl.h
+++ b/src/ipc/client_impl.h
@@ -23,7 +23,7 @@
#include "perfetto/ext/ipc/client.h"
#include "src/ipc/buffered_frame_deserializer.h"
-#include "protos/perfetto/ipc/wire_protocol.pb.h"
+#include "protos/perfetto/ipc/wire_protocol.gen.h"
#include <list>
#include <map>
diff --git a/src/ipc/host_impl.cc b/src/ipc/host_impl.cc
index 1158fb8..7784305 100644
--- a/src/ipc/host_impl.cc
+++ b/src/ipc/host_impl.cc
@@ -26,7 +26,7 @@
#include "perfetto/ext/ipc/service.h"
#include "perfetto/ext/ipc/service_descriptor.h"
-#include "protos/perfetto/ipc/wire_protocol.pb.h"
+#include "protos/perfetto/ipc/wire_protocol.gen.h"
// TODO(primiano): put limits on #connections/uid and req. queue (b/69093705).
diff --git a/src/ipc/host_impl_unittest.cc b/src/ipc/host_impl_unittest.cc
index 4e9216b..61a77dd 100644
--- a/src/ipc/host_impl_unittest.cc
+++ b/src/ipc/host_impl_unittest.cc
@@ -30,7 +30,7 @@
#include "src/ipc/test/test_socket.h"
#include "test/gtest_and_gmock.h"
-#include "protos/perfetto/ipc/wire_protocol.pb.h"
+#include "protos/perfetto/ipc/wire_protocol.gen.h"
#include "src/ipc/test/client_unittest_messages.pb.h"
namespace perfetto {
diff --git a/src/protozero/BUILD.gn b/src/protozero/BUILD.gn
index b2cc13a..23469d8 100644
--- a/src/protozero/BUILD.gn
+++ b/src/protozero/BUILD.gn
@@ -28,6 +28,7 @@
"../../include/perfetto/ext/base", # TODO(primiano): remove this
]
sources = [
+ "field.cc",
"message.cc",
"message_handle.cc",
"packed_repeated_fields.cc",
@@ -35,6 +36,7 @@
"scattered_heap_buffer.cc",
"scattered_stream_null_delegate.cc",
"scattered_stream_writer.cc",
+ "static_buffer.cc",
]
}
@@ -49,6 +51,7 @@
testonly = true
deps = [
":protozero",
+ ":testing_messages_cpp",
":testing_messages_lite",
":testing_messages_zero",
"../../gn:default_deps",
@@ -63,6 +66,7 @@
"proto_decoder_unittest.cc",
"proto_utils_unittest.cc",
"scattered_stream_writer_unittest.cc",
+ "test/cppgen_conformance_unittest.cc",
"test/fake_scattered_buffer.cc",
"test/fake_scattered_buffer.h",
"test/protozero_conformance_unittest.cc",
@@ -72,10 +76,6 @@
# Generates both xxx.pbzero.h and xxx.pb.h (official proto).
perfetto_proto_library("testing_messages_@TYPE@") {
- proto_generators = [
- "lite",
- "zero",
- ]
sources = [
"test/example_proto/library.proto",
"test/example_proto/library_internals/galaxies.proto",
diff --git a/src/protozero/field.cc b/src/protozero/field.cc
new file mode 100644
index 0000000..c92f7ce
--- /dev/null
+++ b/src/protozero/field.cc
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+#include "perfetto/protozero/field.h"
+
+#include "perfetto/base/logging.h"
+
+#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
+// The memcpy() for fixed32/64 below needs to be adjusted if we want to
+// support big endian CPUs. There doesn't seem to be a compelling need today.
+#error Unimplemented for big endian archs.
+#endif
+
+namespace protozero {
+
+void Field::SerializeAndAppendTo(std::string* dst) {
+ namespace pu = proto_utils;
+ size_t initial_size = dst->size();
+ dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
+ uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
+ uint8_t* wptr = start;
+ switch (type_) {
+ case static_cast<int>(pu::ProtoWireType::kVarInt): {
+ wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
+ wptr = pu::WriteVarInt(int_value_, wptr);
+ break;
+ }
+ case static_cast<int>(pu::ProtoWireType::kFixed32): {
+ wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
+ uint32_t value32 = static_cast<uint32_t>(int_value_);
+ memcpy(wptr, &value32, sizeof(value32));
+ wptr += sizeof(uint32_t);
+ break;
+ }
+ case static_cast<int>(pu::ProtoWireType::kFixed64): {
+ wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
+ memcpy(wptr, &int_value_, sizeof(int_value_));
+ wptr += sizeof(uint64_t);
+ break;
+ }
+ case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
+ ConstBytes payload = as_bytes();
+ wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
+ wptr = pu::WriteVarInt(payload.size, wptr);
+ memcpy(wptr, payload.data, payload.size);
+ wptr += payload.size;
+ break;
+ }
+ default:
+ PERFETTO_FATAL("Unknown field type %u", type_);
+ }
+ size_t written_size = static_cast<size_t>(wptr - start);
+ PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
+ PERFETTO_DCHECK(initial_size + written_size <= dst->size());
+ dst->resize(initial_size + written_size);
+}
+
+} // namespace protozero
diff --git a/src/protozero/proto_decoder.cc b/src/protozero/proto_decoder.cc
index bd563fb..9bf9ca5 100644
--- a/src/protozero/proto_decoder.cc
+++ b/src/protozero/proto_decoder.cc
@@ -60,7 +60,10 @@
if (PERFETTO_LIKELY(*pos < 0x80)) { // Fastpath for fields with ID < 16.
preamble = *(pos++);
} else {
- pos = ParseVarInt(pos, end, &preamble);
+ const uint8_t* next = ParseVarInt(pos, end, &preamble);
+ if (PERFETTO_UNLIKELY(pos == next))
+ return res;
+ pos = next;
}
uint32_t field_id = static_cast<uint32_t>(preamble >> kFieldTypeNumBits);
@@ -208,7 +211,7 @@
PERFETTO_CHECK(new_capacity > size_);
std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
- static_assert(PERFETTO_IS_TRIVIALLY_COPYABLE(Field),
+ static_assert(std::is_trivially_copyable<Field>::value,
"Field must be trivially copyable");
memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
diff --git a/src/protozero/proto_utils_unittest.cc b/src/protozero/proto_utils_unittest.cc
index a724189..9124490 100644
--- a/src/protozero/proto_utils_unittest.cc
+++ b/src/protozero/proto_utils_unittest.cc
@@ -194,6 +194,8 @@
}
}
+// ParseVarInt() must fail gracefully if we hit the |end| without seeing the
+// MSB == 0 (i.e. end-of-sequence).
TEST(ProtoUtilsTest, VarIntDecodingOutOfBounds) {
uint8_t buf[] = {0xff, 0xff, 0xff, 0xff};
for (size_t i = 0; i < 5; i++) {
@@ -204,6 +206,27 @@
}
}
+// Even if we see a valid end-of-sequence, ParseVarInt() must fail if the number
+// is larger than 10 bytes. That would cause subtl bugs when trying to shift
+// left by more than 64 bits.
+TEST(ProtoUtilsTest, RejectVarIntTooBig) {
+ // This is the biggest valid varint we support (2**64 - 1).
+ uint8_t good[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01};
+
+ // Parsing this value must succeed.
+ uint64_t value = static_cast<uint64_t>(-1);
+ const uint8_t* res = ParseVarInt(&good[0], &good[sizeof(good)], &value);
+ EXPECT_EQ(&good[sizeof(good)], res);
+ EXPECT_EQ(value, static_cast<uint64_t>(-1ULL));
+
+ uint8_t bad[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x01};
+ value = static_cast<uint64_t>(-1);
+ res = ParseVarInt(&bad[0], &bad[sizeof(bad)], &value);
+ EXPECT_EQ(&bad[0], res);
+ EXPECT_EQ(0u, value);
+}
+
} // namespace
} // namespace proto_utils
} // namespace protozero
diff --git a/src/protozero/protoc_plugin/cppgen_plugin.cc b/src/protozero/protoc_plugin/cppgen_plugin.cc
index bbd2b23..51fb707 100644
--- a/src/protozero/protoc_plugin/cppgen_plugin.cc
+++ b/src/protozero/protoc_plugin/cppgen_plugin.cc
@@ -19,6 +19,7 @@
#include <fstream>
#include <iostream>
+#include <map>
#include <set>
#include <stack>
#include <vector>
@@ -46,16 +47,26 @@
using perfetto::base::ToUpper;
static constexpr auto TYPE_MESSAGE = FieldDescriptor::TYPE_MESSAGE;
+static constexpr auto TYPE_ENUM = FieldDescriptor::TYPE_ENUM;
+static constexpr auto TYPE_SINT32 = FieldDescriptor::TYPE_SINT32;
+static constexpr auto TYPE_SINT64 = FieldDescriptor::TYPE_SINT64;
static const char kHeader[] =
"// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin\n";
-std::string GetProtoHeader(const FileDescriptor* file) {
- return StripSuffix(file->name(), ".proto") + ".pb.h";
+// TODO(primiano): this is temporary to avoid clashes between libprotobuf
+// and protozero-cpp classes. Effectively this causes messages like
+// perfetto.protos.DataSourceDescriptor to be generated as
+// perfetto::DataSourceDescriptor. Once libprotobuf is gone we'll be able to
+// move this back into the protos namespace.
+std::string StripPackage(const std::string& pkg) {
+ return StripSuffix(pkg, ".protos");
}
template <typename T = Descriptor>
-std::string GetFullName(const T* msg, bool with_namespace = false) {
+std::string GetFullName(const T* msg,
+ bool with_namespace = false,
+ const std::string& extra_namespace = "") {
std::string full_type;
full_type.append(msg->name());
for (const Descriptor* par = msg->containing_type(); par;
@@ -63,8 +74,9 @@
full_type.insert(0, par->name() + "_");
}
if (with_namespace) {
- std::vector<std::string> namespaces =
- SplitString(msg->file()->package(), ".");
+ std::string pkg = msg->file()->package();
+ pkg = extra_namespace == "" ? StripPackage(pkg) : pkg;
+ auto namespaces = SplitString(pkg + extra_namespace, ".");
for (auto it = namespaces.rbegin(); it != namespaces.rend(); it++) {
full_type.insert(0, *it + "::");
}
@@ -85,6 +97,9 @@
private:
std::string GetCppType(const FieldDescriptor* field, bool constref) const;
+ std::string GetPackedBuffer(const FieldDescriptor* field) const;
+ std::string GetPackedWireType(const FieldDescriptor* field) const;
+
void GenEnum(const EnumDescriptor*, Printer*) const;
void GenEnumAliases(const EnumDescriptor*, Printer*) const;
void GenClassDecl(const Descriptor*, Printer*) const;
@@ -118,12 +133,14 @@
h_printer.Print(kHeader);
h_printer.Print("#ifndef $g$\n#define $g$\n\n", "g", include_guard);
h_printer.Print("#include <stdint.h>\n");
+ h_printer.Print("#include <bitset>\n");
h_printer.Print("#include <vector>\n");
h_printer.Print("#include <string>\n");
h_printer.Print("#include <type_traits>\n\n");
h_printer.Print("#include \"perfetto/protozero/copyable_ptr.h\"\n");
h_printer.Print("#include \"perfetto/base/export.h\"\n\n");
+ cc_printer.Print("#include \"perfetto/protozero/scattered_heap_buffer.h\"\n");
cc_printer.Print(kHeader);
cc_printer.Print("#pragma GCC diagnostic push\n");
cc_printer.Print("#pragma GCC diagnostic ignored \"-Wfloat-equal\"\n");
@@ -148,8 +165,9 @@
}
}
- // Include the .pb.h for the current file.
- cc_printer.Print("\n#include \"$f$\"\n", "f", GetProtoHeader(file));
+ // Include the .pbzero.h for the current file.
+ std::string inc_base_name = StripSuffix(file->name(), ".proto");
+ cc_printer.Print("\n#include \"$f$.pbzero.h\"\n", "f", inc_base_name);
// Recursively traverse all imports and turn them into #include(s).
std::vector<const FileDescriptor*> imports_to_visit;
@@ -160,7 +178,9 @@
const FileDescriptor* cur = imports_to_visit.back();
imports_to_visit.pop_back();
imports_visited.insert(cur);
- cc_printer.Print("#include \"$f$.h\"\n", "f", get_file_name(cur));
+ std::string base_name = StripSuffix(cur->name(), ".proto");
+ cc_printer.Print("#include \"$f$.gen.h\"\n", "f", base_name);
+ cc_printer.Print("#include \"$f$.pbzero.h\"\n", "f", base_name);
for (int i = 0; i < cur->dependency_count(); i++) {
const FileDescriptor* dep = cur->dependency(i);
if (imports_visited.count(dep) || lazy_imports.count(dep->name()))
@@ -233,27 +253,66 @@
} // while (!recursion_stack.empty())
// Generate forward declarations in the header for proto types.
- h_printer.Print("// Forward declarations for protobuf types.\n");
- std::vector<std::string> namespaces = SplitString(file->package(), ".");
- for (size_t i = 0; i < namespaces.size(); i++)
- h_printer.Print("namespace $n$ {\n", "n", namespaces[i]);
+ // Note: do NOT add #includes to other generated headers (either .gen.h or
+ // .pbzero.h). Doing so is extremely hard to handle at the build-system level
+ // and requires propagating public_deps everywhere.
+ cc_printer.Print("\n");
- for (const Descriptor* msg : all_types)
- h_printer.Print("class $n$;\n", "n", GetFullName(msg));
+ // -- Begin of fwd declarations.
- for (size_t i = 0; i < namespaces.size(); i++)
- h_printer.Print("}\n");
+ // Build up the map of forward declarations.
+ std::multimap<std::string /*namespace*/, std::string /*decl*/> fwd_decls;
+ enum FwdType { kClass, kEnum };
+ auto add_fwd_decl = [&fwd_decls](FwdType cpp_type,
+ const std::string& full_name) {
+ auto dot = full_name.rfind("::");
+ PERFETTO_CHECK(dot != std::string::npos);
+ auto package = full_name.substr(0, dot);
+ auto name = full_name.substr(dot + 2);
+ if (cpp_type == kClass) {
+ fwd_decls.emplace(package, "class " + name + ";");
+ } else {
+ PERFETTO_CHECK(cpp_type == kEnum);
+ fwd_decls.emplace(package, "enum " + name + " : int;");
+ }
+ };
- h_printer.Print("\nnamespace perfetto {\n");
- cc_printer.Print("\nnamespace perfetto {\n");
-
- // Generate fwd declarations for C++ types.
+ for (const Descriptor* msg : all_types) {
+ add_fwd_decl(kClass, GetFullName(msg, true));
+ add_fwd_decl(kClass, GetFullName(msg, true, ".pbzero"));
+ }
for (const EnumDescriptor* enm : all_enums) {
- h_printer.Print("enum $n$ : int;\n", "n", GetFullName(enm));
+ add_fwd_decl(kEnum, GetFullName(enm, true));
}
- for (const Descriptor* msg : all_types)
- h_printer.Print("class $n$;\n", "n", GetFullName(msg));
+ // Emit forward declarations grouping by package.
+ std::string last_package;
+ auto close_last_package = [&last_package, &h_printer] {
+ if (!last_package.empty()) {
+ for (const std::string& ns : SplitString(last_package, "::"))
+ h_printer.Print("} // namespace $ns$\n", "ns", ns);
+ h_printer.Print("\n");
+ }
+ };
+ for (const auto& kv : fwd_decls) {
+ const std::string& package = kv.first;
+ if (package != last_package) {
+ close_last_package();
+ last_package = package;
+ for (const std::string& ns : SplitString(package, "::"))
+ h_printer.Print("namespace $ns$ {\n", "ns", ns);
+ }
+ h_printer.Print("$decl$\n", "decl", kv.second);
+ }
+ close_last_package();
+
+ // -- End of fwd declarations.
+
+ auto namespaces = SplitString(StripPackage(file->package()), ".");
+ for (size_t i = 0; i < namespaces.size(); i++) {
+ h_printer.Print("namespace $n$ {\n", "n", namespaces[i]);
+ cc_printer.Print("namespace $n$ {\n", "n", namespaces[i]);
+ }
// Generate declarations and definitions.
for (const EnumDescriptor* enm : local_enums)
@@ -264,10 +323,12 @@
GenClassDef(msg, &cc_printer);
}
- cc_printer.Print("} // namespace perfetto\n");
- cc_printer.Print("#pragma GCC diagnostic pop\n");
+ for (size_t i = 0; i < namespaces.size(); i++) {
+ h_printer.Print("} // namespace $n$\n", "n", namespaces[i]);
+ cc_printer.Print("} // namespace $n$\n", "n", namespaces[i]);
+ }
- h_printer.Print("} // namespace perfetto\n");
+ cc_printer.Print("#pragma GCC diagnostic pop\n");
h_printer.Print("\n#endif // $g$\n", "g", include_guard);
return true;
@@ -311,6 +372,68 @@
abort(); // for gcc
}
+std::string CppObjGenerator::GetPackedBuffer(
+ const FieldDescriptor* field) const {
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_FIXED32:
+ return "::protozero::PackedFixedSizeInt<uint32_t>";
+ case FieldDescriptor::TYPE_SFIXED32:
+ return "::protozero::PackedFixedSizeInt<int32_t>";
+ case FieldDescriptor::TYPE_FIXED64:
+ return "::protozero::PackedFixedSizeInt<uint64_t>";
+ case FieldDescriptor::TYPE_SFIXED64:
+ return "::protozero::PackedFixedSizeInt<int64_t>";
+ case FieldDescriptor::TYPE_DOUBLE:
+ return "::protozero::PackedFixedSizeInt<double>";
+ case FieldDescriptor::TYPE_FLOAT:
+ return "::protozero::PackedFixedSizeInt<float>";
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_BOOL:
+ return "::protozero::PackedVarInt";
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES:
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_ENUM:
+ case FieldDescriptor::TYPE_GROUP:
+ break; // Will abort()
+ }
+ abort();
+}
+
+std::string CppObjGenerator::GetPackedWireType(
+ const FieldDescriptor* field) const {
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_SFIXED32:
+ case FieldDescriptor::TYPE_FLOAT:
+ return "::protozero::proto_utils::ProtoWireType::kFixed32";
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_SFIXED64:
+ case FieldDescriptor::TYPE_DOUBLE:
+ return "::protozero::proto_utils::ProtoWireType::kFixed64";
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_BOOL:
+ return "::protozero::proto_utils::ProtoWireType::kVarInt";
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES:
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_ENUM:
+ case FieldDescriptor::TYPE_GROUP:
+ break; // Will abort()
+ }
+ abort();
+}
+
void CppObjGenerator::GenEnum(const EnumDescriptor* enum_desc,
Printer* p) const {
std::string full_name = GetFullName(enum_desc);
@@ -368,6 +491,17 @@
GenEnumAliases(nested_enum, p);
}
+ // Generate constants with field numbers.
+ p->Print("enum FieldNumbers {\n");
+ for (int i = 0; i < msg->field_count(); i++) {
+ const FieldDescriptor* field = msg->field(i);
+ std::string name = field->camelcase_name();
+ name[0] = perfetto::base::Uppercase(name[0]);
+ p->Print(" k$n$FieldNumber = $num$,\n", "n", name, "num",
+ std::to_string(field->number()));
+ }
+ p->Print("};\n\n");
+
p->Print("$n$();\n", "n", full_name);
p->Print("~$n$();\n", "n", full_name);
p->Print("$n$($n$&&) noexcept;\n", "n", full_name);
@@ -382,36 +516,58 @@
std::string proto_type = GetFullName(msg, true);
p->Print("// Raw proto decoding.\n");
- p->Print("void ParseRawProto(const std::string&);\n");
- p->Print("// Conversion methods from/to the corresponding protobuf types.\n");
- p->Print("void FromProto(const $p$&);\n", "p", proto_type);
- p->Print("void ToProto($p$*) const;\n", "p", proto_type);
+ p->Print("bool ParseFromArray(const void*, size_t);\n");
+ p->Print("bool ParseRawProto(const std::string& str) {\n");
+ p->Print(" return ParseFromArray(str.data(), str.size());\n");
+ p->Print("}\n");
+
+ p->Print("std::string SerializeAsString() const;\n");
+ p->Print("std::vector<uint8_t> SerializeAsArray() const;\n");
+ p->Print("void Serialize($p$*) const;\n", "p",
+ GetFullName(msg, true, ".pbzero"));
+
+ p->Print("// (DEPRECATED) Conversion methods from/to libprotobuf types.\n");
+ p->Print("// These two will go away soon, see go/perfetto-libprotobuf.\n");
+ p->Print(
+ "template <typename T /*$p$*/> void FromProto(const T& pb_obj) { "
+ "ParseRawProto(pb_obj.SerializeAsString()); }\n",
+ "p", proto_type);
+ p->Print(
+ "template <typename T /*$p$*/> void ToProto(T* pb_obj) const { "
+ "pb_obj->Clear(); pb_obj->ParseFromString(SerializeAsString()); }\n",
+ "p", proto_type);
// Generate accessors.
for (int i = 0; i < msg->field_count(); i++) {
const FieldDescriptor* field = msg->field(i);
+ auto set_bit = "_has_field_.set(" + std::to_string(field->number()) + ")";
p->Print("\n");
if (field->options().lazy()) {
p->Print("const std::string& $n$_raw() const { return $n$_; }\n", "n",
field->lowercase_name());
- p->Print("void set_$n$_raw(const std::string& raw) { $n$_ = raw; }\n",
- "n", field->lowercase_name());
+ p->Print(
+ "void set_$n$_raw(const std::string& raw) { $n$_ = raw; $s$; }\n",
+ "n", field->lowercase_name(), "s", set_bit);
} else if (!field->is_repeated()) {
+ p->Print("bool has_$n$() const { return _has_field_[$bit$]; }\n", "n",
+ field->lowercase_name(), "bit", std::to_string(field->number()));
if (field->type() == TYPE_MESSAGE) {
p->Print("$t$ $n$() const { return *$n$_; }\n", "t",
GetCppType(field, true), "n", field->lowercase_name());
- p->Print("$t$* mutable_$n$() { return $n$_.get(); }\n", "t",
- GetCppType(field, false), "n", field->lowercase_name());
+ p->Print("$t$* mutable_$n$() { $s$; return $n$_.get(); }\n", "t",
+ GetCppType(field, false), "n", field->lowercase_name(), "s",
+ set_bit);
} else {
p->Print("$t$ $n$() const { return $n$_; }\n", "t",
GetCppType(field, true), "n", field->lowercase_name());
- p->Print("void set_$n$($t$ value) { $n$_ = value; }\n", "t",
- GetCppType(field, true), "n", field->lowercase_name());
+ p->Print("void set_$n$($t$ value) { $n$_ = value; $s$; }\n", "t",
+ GetCppType(field, true), "n", field->lowercase_name(), "s",
+ set_bit);
if (field->type() == FieldDescriptor::TYPE_BYTES) {
p->Print(
"void set_$n$(const void* p, size_t s) { "
- "$n$_.assign(reinterpret_cast<const char*>(p), s); }\n",
- "n", field->lowercase_name());
+ "$n$_.assign(reinterpret_cast<const char*>(p), s); $s$; }\n",
+ "n", field->lowercase_name(), "s", set_bit);
}
}
} else { // is_repeated()
@@ -424,6 +580,13 @@
GetCppType(field, false), "n", field->lowercase_name());
p->Print("void clear_$n$() { $n$_.clear(); }\n", "n",
field->lowercase_name());
+ if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
+ p->Print("void add_$n$($t$ value) { $n$_.emplace_back(value); }\n", "t",
+ GetCppType(field, false), "n", field->lowercase_name());
+ }
+ // TODO(primiano): this should be done only for TYPE_MESSAGE. Unfortuntely
+ // we didn't realize before and now we have a bunch of code that does:
+ // *msg->add_int_value() = 42 instead of msg->add_int_value(42).
p->Print("$t$* add_$n$() { $n$_.emplace_back(); return &$n$_.back(); }\n",
"t", GetCppType(field, false), "n", field->lowercase_name());
}
@@ -433,8 +596,10 @@
p->Indent();
// Generate fields.
+ int max_field_id = 1;
for (int i = 0; i < msg->field_count(); i++) {
const FieldDescriptor* field = msg->field(i);
+ max_field_id = std::max(max_field_id, field->number());
if (field->options().lazy()) {
p->Print("std::string $n$_; // [lazy=true]\n", "n",
field->lowercase_name());
@@ -455,6 +620,10 @@
p->Print("// Allows to preserve unknown protobuf fields for compatibility\n");
p->Print("// with future versions of .proto files.\n");
p->Print("std::string unknown_fields_;\n");
+
+ p->Print("\nstd::bitset<$id$> _has_field_{};\n", "id",
+ std::to_string(max_field_id + 1));
+
p->Outdent();
p->Print("};\n\n");
}
@@ -485,104 +654,156 @@
std::string proto_type = GetFullName(msg, true);
- // Genrate the ParseRawProto() method definition.
- p->Print("void $f$::ParseRawProto(const std::string& raw) {\n", "f",
+ // Generate the ParseRawProto() method definition.
+ p->Print("bool $f$::ParseFromArray(const void* raw, size_t size) {\n", "f",
full_name);
p->Indent();
- p->Print("$p$ proto;\n", "p", proto_type);
- p->Print("proto.ParseFromString(raw);\n");
- p->Print("FromProto(proto);\n");
- p->Outdent();
- p->Print("}\n\n");
-
- // Genrate the FromProto() method definition.
- p->Print("void $f$::FromProto(const $p$& proto) {\n", "f", full_name, "p",
- proto_type);
- p->Indent();
for (int i = 0; i < msg->field_count(); i++) {
- p->Print("\n");
const FieldDescriptor* field = msg->field(i);
- if (field->options().lazy()) {
- p->Print("$n$_ = proto.$n$().SerializeAsString();\n", "n",
- field->lowercase_name());
- } else if (!field->is_repeated()) {
- if (field->type() == TYPE_MESSAGE) {
- p->Print("$n$_->FromProto(proto.$n$());\n", "n",
- field->lowercase_name());
- } else {
- p->Print(
- "static_assert(sizeof($n$_) == sizeof(proto.$n$()), \"size "
- "mismatch\");\n",
- "n", field->lowercase_name());
- p->Print("$n$_ = static_cast<decltype($n$_)>(proto.$n$());\n", "n",
- field->lowercase_name());
- }
- } else { // is_repeated()
+ if (field->is_repeated())
p->Print("$n$_.clear();\n", "n", field->lowercase_name());
- p->Print("for (const auto& field : proto.$n$()) {\n", "n",
- field->lowercase_name());
- p->Print(" $n$_.emplace_back();\n", "n", field->lowercase_name());
- if (field->type() == TYPE_MESSAGE) {
- p->Print(" $n$_.back().FromProto(field);\n", "n",
- field->lowercase_name());
- } else {
- p->Print(
- "static_assert(sizeof($n$_.back()) == sizeof(proto.$n$(0)), \"size "
- "mismatch\");\n",
- "n", field->lowercase_name());
- p->Print(
- " $n$_.back() = static_cast<decltype($n$_)::value_type>(field);\n",
- "n", field->lowercase_name());
- }
- p->Print("}\n");
- }
}
- p->Print("unknown_fields_ = proto.unknown_fields();\n");
+ p->Print("unknown_fields_.clear();\n");
+ p->Print("bool packed_error = false;\n");
+ p->Print("\n");
+ p->Print("::protozero::ProtoDecoder dec(raw, size);\n");
+ p->Print("for (auto field = dec.ReadField(); field.valid(); ");
+ p->Print("field = dec.ReadField()) {\n");
+ p->Indent();
+ p->Print("if (field.id() < _has_field_.size()) {\n");
+ p->Print(" _has_field_.set(field.id());\n");
+ p->Print("}\n");
+ p->Print("switch (field.id()) {\n");
+ p->Indent();
+ for (int i = 0; i < msg->field_count(); i++) {
+ const FieldDescriptor* field = msg->field(i);
+ p->Print("case $id$ /* $n$ */:\n", "id", std::to_string(field->number()),
+ "n", field->lowercase_name());
+ p->Indent();
+ if (field->options().lazy()) {
+ p->Print("$n$_ = field.as_std_string();\n", "n", field->lowercase_name());
+ } else {
+ std::string statement;
+ if (field->type() == TYPE_MESSAGE) {
+ statement = "$rval$.ParseRawProto(field.as_std_string());\n";
+ } else {
+ if (field->type() == TYPE_SINT32 || field->type() == TYPE_SINT64) {
+ // sint32/64 fields are special and need to be zig-zag-decoded.
+ statement = "field.get_signed(&$rval$);\n";
+ } else {
+ statement = "field.get(&$rval$);\n";
+ }
+ }
+ if (field->is_packed()) {
+ PERFETTO_CHECK(field->is_repeated());
+ if (field->type() == TYPE_SINT32 || field->type() == TYPE_SINT64) {
+ PERFETTO_FATAL("packed signed (zigzag) fields are not supported");
+ }
+ p->Print(
+ "for (::protozero::PackedRepeatedFieldIterator<$w$, $c$> "
+ "rep(field.data(), field.size(), &packed_error); rep; ++rep) {\n",
+ "w", GetPackedWireType(field), "c", GetCppType(field, false));
+ p->Print(" $n$_.emplace_back(*rep);\n", "n", field->lowercase_name());
+ p->Print("}\n");
+ } else if (field->is_repeated()) {
+ p->Print("$n$_.emplace_back();\n", "n", field->lowercase_name());
+ p->Print(statement.c_str(), "rval",
+ field->lowercase_name() + "_.back()");
+ } else if (field->type() == TYPE_MESSAGE) {
+ p->Print(statement.c_str(), "rval",
+ "(*" + field->lowercase_name() + "_)");
+ } else {
+ p->Print(statement.c_str(), "rval", field->lowercase_name() + "_");
+ }
+ }
+ p->Print("break;\n");
+ p->Outdent();
+ } // for (field)
+ p->Print("default:\n");
+ p->Print(" field.SerializeAndAppendTo(&unknown_fields_);\n");
+ p->Print(" break;\n");
+ p->Outdent();
+ p->Print("}\n"); // switch(field.id)
+ p->Outdent();
+ p->Print("}\n"); // for(field)
+ p->Print("return !packed_error && !dec.bytes_left();\n"); // for(field)
p->Outdent();
p->Print("}\n\n");
- // Genrate the ToProto() method definition.
- p->Print("void $f$::ToProto($p$* proto) const {\n", "f", full_name, "p",
- proto_type);
+ // Generate the SerializeAsString() method definition.
+ p->Print("std::string $f$::SerializeAsString() const {\n", "f", full_name);
p->Indent();
- p->Print("proto->Clear();\n");
+ p->Print("::protozero::HeapBuffered<$p$> msg;\n", "p",
+ GetFullName(msg, true, ".pbzero"));
+ p->Print("Serialize(msg.get());\n");
+ p->Print("return msg.SerializeAsString();\n");
+ p->Outdent();
+ p->Print("}\n\n");
+
+ // Generate the SerializeAsArray() method definition.
+ p->Print("std::vector<uint8_t> $f$::SerializeAsArray() const {\n", "f",
+ full_name);
+ p->Indent();
+ p->Print("::protozero::HeapBuffered<$p$> msg;\n", "p",
+ GetFullName(msg, true, ".pbzero"));
+ p->Print("Serialize(msg.get());\n");
+ p->Print("return msg.SerializeAsArray();\n");
+ p->Outdent();
+ p->Print("}\n\n");
+
+ // Generaate the Serialize() method that writes the fields into the passed
+ // protozero |msg| write-only interface |msg|.
+ p->Print("void $f$::Serialize($p$* msg) const {\n", "f", full_name, "p",
+ GetFullName(msg, true, ".pbzero"));
+ p->Indent();
for (int i = 0; i < msg->field_count(); i++) {
- p->Print("\n");
const FieldDescriptor* field = msg->field(i);
+ std::string fld_name = field->lowercase_name();
if (field->options().lazy()) {
- p->Print("proto->mutable_$n$()->ParseFromString($n$_);\n", "n",
- field->lowercase_name());
- } else if (!field->is_repeated()) {
- if (field->type() == TYPE_MESSAGE) {
- p->Print("$n$_->ToProto(proto->mutable_$n$());\n", "n",
- field->lowercase_name());
- } else {
- p->Print(
- "static_assert(sizeof($n$_) == sizeof(proto->$n$()), \"size "
- "mismatch\");\n",
- "n", field->lowercase_name());
- p->Print("proto->set_$n$(static_cast<decltype(proto->$n$())>($n$_));\n",
- "n", field->lowercase_name());
+ p->Print("msg->set_$n$_raw($n$_);\n", "n", fld_name);
+ } else {
+ std::string enum_type;
+ if (field->type() == TYPE_ENUM)
+ enum_type = GetFullName(field->enum_type(), true, ".pbzero");
+ if (field->is_packed()) {
+ PERFETTO_CHECK(field->is_repeated());
+ p->Print("{\n");
+ p->Indent();
+ p->Print("$p$ pack;\n", "p", GetPackedBuffer(field));
+ p->Print("for (auto& it : $n$_)\n", "n", fld_name);
+ p->Print(" pack.Append(it);\n");
+ p->Print("msg->set_$n$(pack);\n", "n", fld_name);
+ p->Outdent();
+ p->Print("}\n");
+ } else if (field->is_repeated()) {
+ p->Print("for (auto& it : $n$_) {\n", "n", fld_name);
+ if (field->type() == TYPE_MESSAGE) {
+ p->Print(" it.Serialize(msg->add_$n$());\n", "n", fld_name);
+ } else if (field->type() == TYPE_ENUM) {
+ p->Print(" msg->add_$n$(static_cast<::$e$>(it));\n", "n", fld_name,
+ "e", enum_type);
+ } else {
+ p->Print(" msg->add_$n$(it);\n", "n", fld_name);
+ }
+ p->Print("}\n");
+ } else { // repeated = false
+ p->Print("if (_has_field_[$id$]) { ", "id",
+ std::to_string(field->number()));
+ if (field->type() == TYPE_MESSAGE) {
+ p->Print("$n$_->Serialize(msg->set_$n$());", "n", fld_name);
+ } else if (field->type() == TYPE_ENUM) {
+ p->Print("msg->set_$n$(static_cast<::$e$>($n$_));", "n", fld_name,
+ "e", enum_type);
+ } else {
+ p->Print("msg->set_$n$($n$_);", "n", fld_name);
+ }
+ p->Print(" }\n");
}
- } else { // is_repeated()
- p->Print("for (const auto& it : $n$_) {\n", "n", field->lowercase_name());
- if (field->type() == TYPE_MESSAGE) {
- p->Print(" auto* entry = proto->add_$n$();\n", "n",
- field->lowercase_name());
- p->Print(" it.ToProto(entry);\n");
- } else {
- p->Print(
- " proto->add_$n$(static_cast<decltype(proto->$n$(0))>(it));\n",
- "n", field->lowercase_name());
- p->Print(
- "static_assert(sizeof(it) == sizeof(proto->$n$(0)), \"size "
- "mismatch\");\n",
- "n", field->lowercase_name());
- }
- p->Print("}\n");
}
- }
- p->Print("*(proto->mutable_unknown_fields()) = unknown_fields_;\n");
+ } // for (field)
+ p->Print(
+ "msg->AppendRawProtoBytes(unknown_fields_.data(), "
+ "unknown_fields_.size());\n");
p->Outdent();
p->Print("}\n\n");
}
diff --git a/src/protozero/static_buffer.cc b/src/protozero/static_buffer.cc
new file mode 100644
index 0000000..cb4737b
--- /dev/null
+++ b/src/protozero/static_buffer.cc
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#include "perfetto/protozero/static_buffer.h"
+
+#include "perfetto/base/logging.h"
+
+namespace protozero {
+
+StaticBufferDelegate::~StaticBufferDelegate() = default;
+
+ContiguousMemoryRange StaticBufferDelegate::GetNewBuffer() {
+ if (get_new_buffer_called_once_) {
+ // This is the 2nd time GetNewBuffer is called. The estimate is wrong. We
+ // shouldn't try to grow the buffer after the initial call.
+ PERFETTO_FATAL("Static buffer too small");
+ }
+ get_new_buffer_called_once_ = true;
+ return range_;
+}
+
+} // namespace protozero
diff --git a/src/protozero/test/cppgen_conformance_unittest.cc b/src/protozero/test/cppgen_conformance_unittest.cc
new file mode 100644
index 0000000..040b507
--- /dev/null
+++ b/src/protozero/test/cppgen_conformance_unittest.cc
@@ -0,0 +1,342 @@
+/*
+ * 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.
+ */
+
+#include <limits>
+#include <memory>
+#include <vector>
+
+#include "perfetto/protozero/message_handle.h"
+#include "perfetto/protozero/packed_repeated_fields.h"
+#include "test/gtest_and_gmock.h"
+
+// Autogenerated headers in out/*/gen/
+#include "src/protozero/test/example_proto/library.gen.h"
+#include "src/protozero/test/example_proto/test_messages.gen.h"
+#include "src/protozero/test/example_proto/test_messages.pb.h"
+
+// Generated by the cppgen compiler.
+namespace pbtest = protozero::test;
+
+// Generated by the official protobuf compiler.
+namespace pbgold = protozero::test::protos;
+
+namespace protozero {
+namespace {
+
+using testing::ElementsAreArray;
+
+// The two functions below are templated because they are re-used both on the
+// libprotobuf and protozero versions to check both libproto -> zero and
+// zero -> libproto compatibility.
+template <typename T>
+void SetTestingFields(T* msg) {
+ msg->set_field_int32(-1);
+ msg->set_field_int64(-333123456789ll);
+ msg->set_field_uint32(600);
+ msg->set_field_uint64(333123456789ll);
+ msg->set_field_sint32(-5);
+ msg->set_field_sint64(-9000);
+ msg->set_field_fixed32(12345);
+ msg->set_field_fixed64(444123450000ll);
+ msg->set_field_sfixed32(-69999);
+ msg->set_field_sfixed64(-200);
+ msg->set_field_float(3.14f);
+ msg->set_field_double(0.5555);
+ msg->set_field_bool(true);
+
+ msg->set_small_enum(decltype(msg->small_enum())::TO_BE);
+ msg->set_signed_enum(decltype(msg->signed_enum())::NEGATIVE);
+ msg->set_big_enum(decltype(msg->big_enum())::BEGIN);
+
+ msg->set_field_string("FizzBuzz");
+ msg->set_field_bytes(reinterpret_cast<const uint8_t*>("\x11\x00\xBE\xEF"), 4);
+ msg->add_repeated_int32(1);
+ msg->add_repeated_int32(-1);
+ msg->add_repeated_int32(100);
+ msg->add_repeated_int32(2000000);
+}
+
+template <typename T>
+void CheckTestingFields(const T& msg) {
+ EXPECT_EQ(-1, msg.field_int32());
+ EXPECT_EQ(-333123456789ll, msg.field_int64());
+ EXPECT_EQ(600u, msg.field_uint32());
+ EXPECT_EQ(333123456789ull, msg.field_uint64());
+ EXPECT_EQ(-5, msg.field_sint32());
+ EXPECT_EQ(-9000, msg.field_sint64());
+ EXPECT_EQ(12345u, msg.field_fixed32());
+ EXPECT_EQ(444123450000ull, msg.field_fixed64());
+ EXPECT_EQ(-69999, msg.field_sfixed32());
+ EXPECT_EQ(-200, msg.field_sfixed64());
+ EXPECT_FLOAT_EQ(3.14f, msg.field_float());
+ EXPECT_DOUBLE_EQ(0.5555, msg.field_double());
+ EXPECT_EQ(true, msg.field_bool());
+ EXPECT_EQ(decltype(msg.small_enum())::TO_BE, msg.small_enum());
+ EXPECT_EQ(decltype(msg.signed_enum())::NEGATIVE, msg.signed_enum());
+ EXPECT_EQ(decltype(msg.big_enum())::BEGIN, msg.big_enum());
+ EXPECT_EQ("FizzBuzz", msg.field_string());
+ EXPECT_EQ(std::string("\x11\x00\xBE\xEF", 4), msg.field_bytes());
+ ASSERT_THAT(msg.repeated_int32(), ElementsAreArray({1, -1, 100, 2000000}));
+}
+
+TEST(ProtoCppConformanceTest, GenEncode_GoldDecode) {
+ pbtest::EveryField msg;
+ SetTestingFields(&msg);
+ std::string serialized = msg.SerializeAsString();
+
+ pbgold::EveryField gold_msg;
+ gold_msg.ParseFromString(serialized);
+ CheckTestingFields(gold_msg);
+ EXPECT_EQ(serialized.size(), static_cast<size_t>(gold_msg.ByteSize()));
+}
+
+TEST(ProtoCppConformanceTest, GoldEncode_GenDecode) {
+ pbgold::EveryField gold_msg;
+ SetTestingFields(&gold_msg);
+ std::string serialized = gold_msg.SerializeAsString();
+
+ pbtest::EveryField msg;
+ EXPECT_TRUE(msg.ParseRawProto(serialized));
+ CheckTestingFields(msg);
+}
+
+TEST(ProtoCppConformanceTest, GenEncode_GenDecode) {
+ pbtest::EveryField msg;
+ SetTestingFields(&msg);
+ std::string serialized = msg.SerializeAsString();
+
+ pbtest::EveryField dec_msg;
+ dec_msg.ParseRawProto(serialized);
+ CheckTestingFields(dec_msg);
+ EXPECT_EQ(serialized.size(), dec_msg.SerializeAsString().size());
+}
+
+TEST(ProtoCppConformanceTest, NestedMessages) {
+ pbtest::NestedA msg_a;
+ pbtest::NestedA::NestedB* msg_b = msg_a.add_repeated_a();
+ pbtest::NestedA::NestedB::NestedC* msg_c = msg_b->mutable_value_b();
+ msg_c->set_value_c(321);
+ msg_b = msg_a.add_repeated_a();
+ msg_a.mutable_super_nested()->set_value_c(1000);
+ std::string serialized = msg_a.SerializeAsString();
+
+ pbgold::NestedA gold_msg_a;
+ gold_msg_a.ParseFromString(serialized);
+ EXPECT_EQ(2, gold_msg_a.repeated_a_size());
+ EXPECT_EQ(321, gold_msg_a.repeated_a(0).value_b().value_c());
+ EXPECT_FALSE(gold_msg_a.repeated_a(1).has_value_b());
+ EXPECT_EQ(gold_msg_a.repeated_a(1).value_b().value_c(), 0);
+ EXPECT_EQ(1000, gold_msg_a.super_nested().value_c());
+}
+
+// Tests that unknown fields are preserved when re-serializing. This test uses
+// the messages NestedA and NestedA_V2, where NestedA_V2 mimics a future
+// extension of NestedA. It starts filling the V2 version, than decodes it with
+// V1, then re-encodes V1 and decodes with V2 and finally check that all the V2
+// original fields have been preserved.
+TEST(ProtoCppConformanceTest, PreserveUnknownFields) {
+ std::string serialized;
+ {
+ pbtest::TestVersioning_V2 msg_v2;
+ msg_v2.set_root_int(10);
+ msg_v2.set_root_int_v2(11);
+ msg_v2.add_enumz(pbtest::TestVersioning_V2::ONE);
+ msg_v2.add_enumz(pbtest::TestVersioning_V2::TWO);
+ msg_v2.add_enumz(pbtest::TestVersioning_V2::THREE_V2);
+ msg_v2.set_root_string("root-string");
+ msg_v2.add_rep_string("root-rep-string-1");
+ msg_v2.add_rep_string("root-rep-string-2");
+ for (int i = 0; i < 3; i++) {
+ auto* sub1 = i == 0 ? msg_v2.mutable_sub1() : msg_v2.add_sub1_rep();
+ sub1->set_sub1_int(12);
+ sub1->set_sub1_string("sub1-string");
+ sub1->set_sub1_int_v2(13);
+ sub1->set_sub1_string_v2("sub1-string-v2");
+
+ auto* sub2 = i == 0 ? msg_v2.mutable_sub2() : msg_v2.add_sub2_rep();
+ sub2->set_sub2_int(14);
+ sub2->set_sub2_string("sub2-string");
+ }
+ {
+ pbtest::TestVersioning_V2::Sub1_V2 lazy;
+ lazy.set_sub1_int(15);
+ lazy.set_sub1_string("sub1-lazy-string");
+ lazy.set_sub1_int_v2(16);
+ lazy.set_sub1_string_v2("sub1-lazy-string-v2");
+ msg_v2.set_sub1_lazy_raw(lazy.SerializeAsString());
+ }
+ {
+ pbtest::TestVersioning_V2::Sub2_V2 lazy;
+ lazy.set_sub2_int(17);
+ lazy.set_sub2_string("sub2-v2-lazy-string");
+ msg_v2.set_sub2_lazy_raw(lazy.SerializeAsString());
+ }
+
+ serialized = msg_v2.SerializeAsString();
+ }
+
+ // Now decode with an earlier version that has less fields. Then re-serialize
+ // the v1 message.
+ {
+ pbtest::TestVersioning_V1 msg_v1;
+ EXPECT_TRUE(msg_v1.ParseRawProto(serialized));
+ EXPECT_EQ(msg_v1.root_int(), 10);
+ EXPECT_EQ(msg_v1.enumz_size(), 3);
+ // These are to workaround "ODR-usage" rules that would require that the
+ // constexpr in the .gen.h file have a matching symbol definition in the .cc
+ // file.
+ const auto ONE = pbtest::TestVersioning_V1::ONE;
+ const auto TWO = pbtest::TestVersioning_V1::TWO;
+ EXPECT_EQ(msg_v1.enumz()[0], ONE);
+ EXPECT_EQ(msg_v1.enumz()[1], TWO);
+ EXPECT_EQ(static_cast<int>(msg_v1.enumz()[2]), 3);
+ EXPECT_EQ(msg_v1.root_string(), "root-string");
+ EXPECT_EQ(msg_v1.rep_string_size(), 2);
+ EXPECT_EQ(msg_v1.rep_string()[0], "root-rep-string-1");
+ EXPECT_EQ(msg_v1.rep_string()[1], "root-rep-string-2");
+ EXPECT_EQ(msg_v1.sub1_rep_size(), 2);
+ for (size_t i = 0; i < 3; i++) {
+ auto* sub1 = i == 0 ? &msg_v1.sub1() : &msg_v1.sub1_rep()[i - 1];
+ EXPECT_EQ(sub1->sub1_int(), 12);
+ EXPECT_EQ(sub1->sub1_string(), "sub1-string");
+ }
+
+ // Append an extra field and change the valaue of an existing one before
+ // re-serializing.
+ msg_v1.set_root_int(101);
+ msg_v1.add_rep_string("extra-string");
+ serialized = msg_v1.SerializeAsString();
+ }
+
+ // Decode the re-serialized v1 message with with v2. Check that the _v2
+ // fields have been preserved in the double de/serializataion across versions.
+ {
+ pbtest::TestVersioning_V2 msg_v2;
+ EXPECT_TRUE(msg_v2.ParseRawProto(serialized));
+ EXPECT_EQ(msg_v2.root_int(), 101);
+ EXPECT_EQ(msg_v2.root_int_v2(), 11);
+ EXPECT_EQ(msg_v2.enumz_size(), 3);
+ const auto ONE = pbtest::TestVersioning_V2::ONE;
+ const auto TWO = pbtest::TestVersioning_V2::TWO;
+ const auto THREE_V2 = pbtest::TestVersioning_V2::THREE_V2;
+ EXPECT_EQ(msg_v2.enumz()[0], ONE);
+ EXPECT_EQ(msg_v2.enumz()[1], TWO);
+ EXPECT_EQ(msg_v2.enumz()[2], THREE_V2);
+ EXPECT_EQ(msg_v2.root_string(), "root-string");
+ EXPECT_EQ(msg_v2.rep_string_size(), 3);
+ EXPECT_EQ(msg_v2.rep_string()[0], "root-rep-string-1");
+ EXPECT_EQ(msg_v2.rep_string()[1], "root-rep-string-2");
+ EXPECT_EQ(msg_v2.rep_string()[2], "extra-string");
+ EXPECT_EQ(msg_v2.sub1_rep_size(), 2);
+ for (size_t i = 0; i < 3; i++) {
+ auto* sub1 = i == 0 ? &msg_v2.sub1() : &msg_v2.sub1_rep()[i - 1];
+ EXPECT_EQ(sub1->sub1_int(), 12);
+ EXPECT_EQ(sub1->sub1_string(), "sub1-string");
+ EXPECT_EQ(sub1->sub1_int_v2(), 13);
+ EXPECT_EQ(sub1->sub1_string_v2(), "sub1-string-v2");
+ auto* sub2 = i == 0 ? &msg_v2.sub2() : &msg_v2.sub2_rep()[i - 1];
+ EXPECT_EQ(sub2->sub2_int(), 14);
+ EXPECT_EQ(sub2->sub2_string(), "sub2-string");
+ }
+ {
+ pbtest::TestVersioning_V2::Sub1_V2 lazy;
+ EXPECT_TRUE(lazy.ParseRawProto(msg_v2.sub1_lazy_raw()));
+ EXPECT_EQ(lazy.sub1_int(), 15);
+ EXPECT_EQ(lazy.sub1_string(), "sub1-lazy-string");
+ EXPECT_EQ(lazy.sub1_int_v2(), 16);
+ EXPECT_EQ(lazy.sub1_string_v2(), "sub1-lazy-string-v2");
+ }
+ {
+ pbtest::TestVersioning_V2::Sub2_V2 lazy;
+ EXPECT_TRUE(lazy.ParseRawProto(msg_v2.sub2_lazy_raw()));
+ EXPECT_EQ(lazy.sub2_int(), 17);
+ EXPECT_EQ(lazy.sub2_string(), "sub2-v2-lazy-string");
+ }
+ }
+}
+
+// Checks that unset fields aren't zero-initialized in the decode -> re-encode
+// process.
+TEST(ProtoCppConformanceTest, DontDefaultInitialize) {
+ pbtest::EveryField msg;
+ EXPECT_FALSE(msg.has_field_int32());
+ msg.set_field_int32(0);
+ EXPECT_TRUE(msg.has_field_int32());
+
+ EXPECT_FALSE(msg.has_field_float());
+ msg.set_field_float(.0f);
+ EXPECT_TRUE(msg.has_field_float());
+
+ EXPECT_FALSE(msg.has_field_string());
+ msg.set_field_string("");
+ EXPECT_TRUE(msg.has_field_string());
+
+ pbtest::EveryField dec;
+ dec.ParseRawProto(msg.SerializeAsString());
+ std::string reserialized = dec.SerializeAsString();
+
+ pbgold::EveryField gold_msg;
+ gold_msg.ParseFromString(reserialized);
+ EXPECT_TRUE(gold_msg.has_field_int32());
+ EXPECT_EQ(gold_msg.field_int32(), 0);
+ EXPECT_TRUE(gold_msg.has_field_float());
+ EXPECT_FLOAT_EQ(gold_msg.field_float(), .0f);
+ EXPECT_TRUE(gold_msg.has_field_string());
+ EXPECT_EQ(gold_msg.field_string(), "");
+ EXPECT_FALSE(gold_msg.has_field_int64());
+ EXPECT_FALSE(gold_msg.has_field_uint64());
+ EXPECT_FALSE(gold_msg.has_field_bytes());
+}
+
+// Tests serialization and deserialization of packed encoding fields.
+TEST(ProtoCppConformanceTest, PackedRepeatedFields) {
+ std::string serialized;
+ {
+ pbtest::PackedRepeatedFields msg;
+
+ for (int i = -100; i < 100; i++)
+ msg.add_field_int32(i);
+
+ for (uint32_t i = 100; i < 200; i++)
+ msg.add_field_fixed32(i);
+
+ for (int64_t i = 5000000000; i < 5000001000; i++)
+ msg.add_field_sfixed64(i);
+
+ serialized = msg.SerializeAsString();
+ }
+ {
+ pbtest::PackedRepeatedFields msg;
+ EXPECT_TRUE(msg.ParseRawProto(serialized));
+
+ std::vector<int> exp_int32;
+ for (int i = -100; i < 100; i++)
+ exp_int32.emplace_back(i);
+ ASSERT_THAT(msg.field_int32(), ElementsAreArray(exp_int32));
+
+ std::vector<uint32_t> exp_fixed32;
+ for (uint32_t i = 100; i < 200; i++)
+ exp_fixed32.emplace_back(i);
+ ASSERT_THAT(msg.field_fixed32(), ElementsAreArray(exp_fixed32));
+
+ std::vector<int64_t> exp_sfixed64;
+ for (int64_t i = 5000000000; i < 5000001000; i++)
+ exp_sfixed64.emplace_back(i);
+ ASSERT_THAT(msg.field_sfixed64(), ElementsAreArray(exp_sfixed64));
+ }
+}
+} // namespace
+} // namespace protozero
diff --git a/src/protozero/test/example_proto/test_messages.proto b/src/protozero/test/example_proto/test_messages.proto
index db8212c..298b77f 100644
--- a/src/protozero/test/example_proto/test_messages.proto
+++ b/src/protozero/test/example_proto/test_messages.proto
@@ -104,3 +104,56 @@
repeated fixed32 field_fixed32 = 2 [packed = true];
repeated sfixed64 field_sfixed64 = 3 [packed = true];
}
+
+// The following two messages are for testing that unknown fields being
+// preserved in the decode->reencode path.
+
+message TestVersioning_V1 {
+ enum Enumz_V1 {
+ ONE = 1;
+ TWO = 2;
+ }
+ message Sub1_V1 {
+ optional int32 sub1_int = 1;
+ optional string sub1_string = 2;
+ }
+ optional int32 root_int = 1;
+ repeated Enumz_V1 enumz = 2;
+ optional string root_string = 3;
+ repeated string rep_string = 4;
+ optional Sub1_V1 sub1 = 5;
+ repeated Sub1_V1 sub1_rep = 6;
+ optional Sub1_V1 sub1_lazy = 7 [lazy = true];
+}
+
+message TestVersioning_V2 {
+ enum Enumz_V2 {
+ ONE = 1;
+ TWO = 2;
+ THREE_V2 = 3;
+ }
+ message Sub1_V2 {
+ optional int32 sub1_int = 1;
+ optional string sub1_string = 2;
+ optional int32 sub1_int_v2 = 3; // New in v2.
+ optional string sub1_string_v2 = 4; // New in v2.
+ }
+ message Sub2_V2 { // New in v2.
+ optional int32 sub2_int = 1;
+ optional string sub2_string = 2;
+ }
+
+ optional int32 root_int = 1;
+ repeated Enumz_V2 enumz = 2;
+ optional string root_string = 3;
+ repeated string rep_string = 4;
+ optional Sub1_V2 sub1 = 5;
+ repeated Sub1_V2 sub1_rep = 6;
+ optional Sub1_V2 sub1_lazy = 7 [lazy = true];
+
+ // New fields introduced in V2.
+ optional int32 root_int_v2 = 10;
+ optional Sub2_V2 sub2 = 11;
+ repeated Sub2_V2 sub2_rep = 12;
+ optional Sub2_V2 sub2_lazy = 13 [lazy = true];
+}
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 80d394d..a096cd2 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -357,6 +357,7 @@
perfetto_unittest_source_set("unittests") {
testonly = true
sources = [
+ "basic_types_unittest.cc",
"clock_tracker_unittest.cc",
"event_tracker_unittest.cc",
"forwarding_trace_parser_unittest.cc",
diff --git a/src/trace_processor/basic_types_unittest.cc b/src/trace_processor/basic_types_unittest.cc
new file mode 100644
index 0000000..a2a0fd2
--- /dev/null
+++ b/src/trace_processor/basic_types_unittest.cc
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#include "perfetto/trace_processor/basic_types.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+
+TEST(SqlValueTest, DifferentTypes) {
+ ASSERT_LT(SqlValue(), SqlValue::Long(10));
+ ASSERT_LT(SqlValue::Long(10), SqlValue::Double(10.0));
+ ASSERT_LT(SqlValue::Double(10.0), SqlValue::String("10"));
+}
+
+TEST(SqlValueTest, CompareLong) {
+ SqlValue int32_min = SqlValue::Long(std::numeric_limits<int32_t>::min());
+ SqlValue minus_1 = SqlValue::Long(-1);
+ SqlValue zero = SqlValue::Long(0);
+ SqlValue uint32_max = SqlValue::Long(std::numeric_limits<uint32_t>::max());
+
+ ASSERT_LT(int32_min, minus_1);
+ ASSERT_LT(int32_min, uint32_max);
+ ASSERT_LT(minus_1, uint32_max);
+
+ ASSERT_GT(uint32_max, zero);
+
+ ASSERT_EQ(zero, zero);
+}
+
+TEST(SqlValueTest, CompareDouble) {
+ SqlValue int32_min = SqlValue::Double(std::numeric_limits<int32_t>::min());
+ SqlValue minus_1 = SqlValue::Double(-1.0);
+ SqlValue zero = SqlValue::Double(0);
+ SqlValue uint32_max = SqlValue::Double(std::numeric_limits<uint32_t>::max());
+
+ ASSERT_LT(int32_min, minus_1);
+ ASSERT_LT(int32_min, uint32_max);
+ ASSERT_LT(minus_1, uint32_max);
+
+ ASSERT_GT(uint32_max, zero);
+
+ ASSERT_EQ(zero, zero);
+}
+
+TEST(SqlValueTest, CompareString) {
+ SqlValue a = SqlValue::String("a");
+ SqlValue aa = SqlValue::String("aa");
+ SqlValue b = SqlValue::String("b");
+
+ ASSERT_LT(a, aa);
+ ASSERT_LT(aa, b);
+ ASSERT_LT(a, b);
+
+ ASSERT_GT(aa, a);
+
+ ASSERT_EQ(a, a);
+ ASSERT_EQ(aa, SqlValue::String("aa"));
+}
+
+} // namespace
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/clock_tracker.cc b/src/trace_processor/clock_tracker.cc
index 87559e0..696a110 100644
--- a/src/trace_processor/clock_tracker.cc
+++ b/src/trace_processor/clock_tracker.cc
@@ -38,22 +38,56 @@
ClockTracker::~ClockTracker() = default;
-void ClockTracker::AddSnapshot(const std::map<ClockId, int64_t>& clocks) {
+void ClockTracker::AddSnapshot(const std::vector<ClockValue>& clocks) {
const auto snapshot_id = cur_snapshot_id_++;
// Compute the fingerprint of the snapshot by hashing all clock ids. This is
// used by the clock pathfinding logic.
base::Hash hasher;
- for (const auto& id_and_ts : clocks)
- hasher.Update(id_and_ts.first);
+ for (const auto& clock : clocks)
+ hasher.Update(clock.clock_id);
const auto snapshot_hash = static_cast<SnapshotHash>(hasher.digest());
// Add a new entry in each clock's snapshot vector.
- for (const auto& id_and_ts : clocks) {
- ClockId clock_id = id_and_ts.first;
- ClockDomain& clock = clocks_[clock_id];
- const int64_t timestamp_ns = clock.ToNs(id_and_ts.second);
- ClockSnapshots& vect = clock.snapshots[snapshot_hash];
+ for (const auto& clock : clocks) {
+ ClockId clock_id = clock.clock_id;
+ ClockDomain& domain = clocks_[clock_id];
+ if (domain.snapshots.empty()) {
+ if (clock.is_incremental && !ClockIsSeqScoped(clock_id)) {
+ PERFETTO_ELOG("Clock sync error: the global clock with id=%" PRIu64
+ " cannot use incremental encoding; this is only "
+ "supported for sequence-scoped clocks.",
+ clock_id);
+ context_->storage->IncrementStats(stats::invalid_clock_snapshots);
+ return;
+ }
+ domain.unit_multiplier_ns = clock.unit_multiplier_ns;
+ domain.is_incremental = clock.is_incremental;
+ } else if (PERFETTO_UNLIKELY(
+ domain.unit_multiplier_ns != clock.unit_multiplier_ns ||
+ domain.is_incremental != clock.is_incremental)) {
+ PERFETTO_ELOG("Clock sync error: the clock domain with id=%" PRIu64
+ " (unit=%" PRIu64
+ ", incremental=%d), was previously registered with "
+ "different properties (unit=%" PRIu64 ", incremental=%d).",
+ clock_id, clock.unit_multiplier_ns, clock.is_incremental,
+ domain.unit_multiplier_ns, domain.is_incremental);
+ context_->storage->IncrementStats(stats::invalid_clock_snapshots);
+ return;
+ }
+ const int64_t timestamp_ns =
+ clock.absolute_timestamp * domain.unit_multiplier_ns;
+ domain.last_timestamp_ns = timestamp_ns;
+
+ ClockSnapshots& vect = domain.snapshots[snapshot_hash];
+ if (!vect.snapshot_ids.empty() &&
+ PERFETTO_UNLIKELY(vect.snapshot_ids.back() == snapshot_id)) {
+ PERFETTO_ELOG("Clock sync error: duplicate clock domain with id=%" PRIu64
+ " at snapshot %" PRIu32 ".",
+ clock_id, snapshot_id);
+ context_->storage->IncrementStats(stats::invalid_clock_snapshots);
+ return;
+ }
// Clock ids in the range [64, 128) are sequence-scoped and must be
// translated to global ids via SeqScopedClockIdToGlobal() before calling
@@ -110,11 +144,11 @@
auto it2 = it1;
++it2;
for (; it2 != clocks.end(); ++it2) {
- if (!non_monotonic_clocks_.count(it1->first))
- graph_.emplace(it1->first, it2->first, snapshot_hash);
+ if (!non_monotonic_clocks_.count(it1->clock_id))
+ graph_.emplace(it1->clock_id, it2->clock_id, snapshot_hash);
- if (!non_monotonic_clocks_.count(it2->first))
- graph_.emplace(it2->first, it1->first, snapshot_hash);
+ if (!non_monotonic_clocks_.count(it2->clock_id))
+ graph_.emplace(it2->clock_id, it1->clock_id, snapshot_hash);
}
}
}
@@ -176,15 +210,15 @@
// Iterate trough the path found and translate timestamps onto the new clock
// domain on each step, until the target domain is reached.
- int64_t ns = GetClock(src_clock_id).ToNs(src_timestamp);
+ int64_t ns = GetClock(src_clock_id)->ToNs(src_timestamp);
for (uint32_t i = 0; i < path.len; ++i) {
const ClockGraphEdge edge = path.at(i);
- const ClockDomain& cur_clock = GetClock(std::get<0>(edge));
- const ClockDomain& next_clock = GetClock(std::get<1>(edge));
+ ClockDomain* cur_clock = GetClock(std::get<0>(edge));
+ ClockDomain* next_clock = GetClock(std::get<1>(edge));
const SnapshotHash hash = std::get<2>(edge);
// Find the closest timestamp within the snapshots of the source clock.
- const ClockSnapshots& cur_snap = cur_clock.GetSnapshot(hash);
+ const ClockSnapshots& cur_snap = cur_clock->GetSnapshot(hash);
const auto& ts_vec = cur_snap.timestamps_ns;
auto it = std::upper_bound(ts_vec.begin(), ts_vec.end(), ns);
if (it != ts_vec.begin())
@@ -199,7 +233,7 @@
// And use that to retrieve the corresponding time in the next clock domain.
// The snapshot id must exist in the target clock domain. If it doesn't
// either the hash logic or the pathfinding logic are bugged.
- const ClockSnapshots& next_snap = next_clock.GetSnapshot(hash);
+ const ClockSnapshots& next_snap = next_clock->GetSnapshot(hash);
auto next_it = std::lower_bound(next_snap.snapshot_ids.begin(),
next_snap.snapshot_ids.end(), snapshot_id);
PERFETTO_DCHECK(next_it != next_snap.snapshot_ids.end() &&
diff --git a/src/trace_processor/clock_tracker.h b/src/trace_processor/clock_tracker.h
index 6c83bb1..c261249 100644
--- a/src/trace_processor/clock_tracker.h
+++ b/src/trace_processor/clock_tracker.h
@@ -124,12 +124,35 @@
return (static_cast<uint64_t>(seq_id) << 32) | clock_id;
}
+ // Returns whether |global_clock_id| represents a sequence-scoped clock, i.e.
+ // a ClockId returned by SeqScopedClockIdToGlobal().
+ static bool ClockIsSeqScoped(ClockId global_clock_id) {
+ // If the id is > 2**32, this is a sequence-scoped clock id translated into
+ // the global namespace.
+ return (global_clock_id >> 32) > 0;
+ }
+
explicit ClockTracker(TraceProcessorContext*);
virtual ~ClockTracker();
+ // Clock description and its value in a snapshot.
+ struct ClockValue {
+ ClockValue(ClockId id, int64_t ts) : clock_id(id), absolute_timestamp(ts) {}
+ ClockValue(ClockId id, int64_t ts, int64_t unit, bool incremental)
+ : clock_id(id),
+ absolute_timestamp(ts),
+ unit_multiplier_ns(unit),
+ is_incremental(incremental) {}
+
+ ClockId clock_id;
+ int64_t absolute_timestamp;
+ int64_t unit_multiplier_ns = 1;
+ bool is_incremental = false;
+ };
+
// Appends a new snapshot for the given clock domains.
// This is typically called by the code that reads the ClockSnapshot packet.
- void AddSnapshot(const std::map<ClockId, int64_t>&);
+ void AddSnapshot(const std::vector<ClockValue>&);
base::Optional<int64_t> Convert(ClockId src_clock_id,
int64_t src_timestamp,
@@ -193,8 +216,27 @@
// One time-series for each hash.
std::map<SnapshotHash, ClockSnapshots> snapshots;
- // TODO(primiano): support other resolutions.
- int64_t ToNs(int64_t timestamp) const { return timestamp * 1; }
+ // Multiplier for timestamps given in this domain.
+ int64_t unit_multiplier_ns = 1;
+
+ // Whether this clock domain encodes timestamps as deltas. This is only
+ // supported on sequence-local domains.
+ bool is_incremental = false;
+
+ // If |is_incremental| is true, this stores the most recent absolute
+ // timestamp in nanoseconds.
+ int64_t last_timestamp_ns = 0;
+
+ // Treats |timestamp| as delta timestamp if the clock uses incremental
+ // encoding, and as absolute timestamp otherwise.
+ int64_t ToNs(int64_t timestamp) {
+ if (!is_incremental)
+ return timestamp * unit_multiplier_ns;
+
+ int64_t delta_ns = timestamp * unit_multiplier_ns;
+ last_timestamp_ns += delta_ns;
+ return last_timestamp_ns;
+ }
const ClockSnapshots& GetSnapshot(uint32_t hash) const {
auto it = snapshots.find(hash);
@@ -208,10 +250,10 @@
ClockPath FindPath(ClockId src, ClockId target);
- const ClockDomain& GetClock(ClockId clock_id) const {
+ ClockDomain* GetClock(ClockId clock_id) {
auto it = clocks_.find(clock_id);
PERFETTO_DCHECK(it != clocks_.end());
- return it->second;
+ return &it->second;
}
TraceProcessorContext* const context_;
diff --git a/src/trace_processor/clock_tracker_unittest.cc b/src/trace_processor/clock_tracker_unittest.cc
index 824728b..e1628af 100644
--- a/src/trace_processor/clock_tracker_unittest.cc
+++ b/src/trace_processor/clock_tracker_unittest.cc
@@ -158,6 +158,55 @@
EXPECT_EQ(*ct_.Convert(MONOTONIC_RAW, 753, REALTIME), 753 - 1 - 50 + 9000);
}
+TEST_F(ClockTrackerTest, SequenceScopedClocks) {
+ ct_.AddSnapshot({{MONOTONIC, 1000}, {BOOTTIME, 100000}});
+
+ ClockTracker::ClockId c64_1 = ct_.SeqScopedClockIdToGlobal(1, 64);
+ ClockTracker::ClockId c65_1 = ct_.SeqScopedClockIdToGlobal(1, 65);
+ ClockTracker::ClockId c66_1 = ct_.SeqScopedClockIdToGlobal(1, 66);
+ ClockTracker::ClockId c66_2 = ct_.SeqScopedClockIdToGlobal(2, 64);
+
+ ct_.AddSnapshot(
+ {{MONOTONIC, 10000},
+ {c64_1, 100000},
+ {c65_1, 100, /*unit_multiplier_ns=*/1000, /*is_incremental=*/false},
+ {c66_1, 10, /*unit_multiplier_ns=*/1000, /*is_incremental=*/true}});
+
+ // c64_1 is non-incremental and in nanos.
+ EXPECT_EQ(*ct_.Convert(c64_1, 150000, MONOTONIC), 60000);
+ EXPECT_EQ(*ct_.Convert(c64_1, 150000, BOOTTIME), 159000);
+ EXPECT_EQ(*ct_.ToTraceTime(c64_1, 150000), 159000);
+
+ // c65_1 is non-incremental and in micros.
+ EXPECT_EQ(*ct_.Convert(c65_1, 150, MONOTONIC), 60000);
+ EXPECT_EQ(*ct_.Convert(c65_1, 150, BOOTTIME), 159000);
+ EXPECT_EQ(*ct_.ToTraceTime(c65_1, 150), 159000);
+
+ // c66_1 is incremental and in micros.
+ EXPECT_EQ(*ct_.Convert(c66_1, 1 /* abs 11 */, MONOTONIC), 11000);
+ EXPECT_EQ(*ct_.Convert(c66_1, 1 /* abs 12 */, MONOTONIC), 12000);
+ EXPECT_EQ(*ct_.Convert(c66_1, 1 /* abs 13 */, BOOTTIME), 112000);
+ EXPECT_EQ(*ct_.ToTraceTime(c66_1, 2 /* abs 15 */), 114000);
+
+ ct_.AddSnapshot(
+ {{MONOTONIC, 20000},
+ {c66_1, 20, /*unit_multiplier_ns=*/1000, /*is_incremental=*/true}});
+ ct_.AddSnapshot(
+ {{MONOTONIC, 20000},
+ {c66_2, 20, /*unit_multiplier_ns=*/1000, /*is_incremental=*/true}});
+
+ // c66_1 and c66_2 are both incremental and in micros, but shouldn't affect
+ // each other.
+ EXPECT_EQ(*ct_.Convert(c66_1, 1 /* abs 21 */, MONOTONIC), 21000);
+ EXPECT_EQ(*ct_.Convert(c66_2, 2 /* abs 22 */, MONOTONIC), 22000);
+ EXPECT_EQ(*ct_.Convert(c66_1, 1 /* abs 22 */, MONOTONIC), 22000);
+ EXPECT_EQ(*ct_.Convert(c66_2, 2 /* abs 24 */, MONOTONIC), 24000);
+ EXPECT_EQ(*ct_.Convert(c66_1, 1 /* abs 23 */, BOOTTIME), 122000);
+ EXPECT_EQ(*ct_.Convert(c66_2, 2 /* abs 26 */, BOOTTIME), 125000);
+ EXPECT_EQ(*ct_.ToTraceTime(c66_1, 2 /* abs 25 */), 124000);
+ EXPECT_EQ(*ct_.ToTraceTime(c66_2, 4 /* abs 30 */), 129000);
+}
+
} // namespace
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/db/bit_vector_benchmark.cc b/src/trace_processor/db/bit_vector_benchmark.cc
index 6c896d1..54c00f9 100644
--- a/src/trace_processor/db/bit_vector_benchmark.cc
+++ b/src/trace_processor/db/bit_vector_benchmark.cc
@@ -22,6 +22,20 @@
using perfetto::trace_processor::BitVector;
+bool IsBenchmarkFunctionalOnly() {
+ return getenv("BENCHMARK_FUNCTIONAL_TEST_ONLY") != nullptr;
+}
+
+void BitVectorArgs(benchmark::internal::Benchmark* b) {
+ b->Arg(64);
+
+ if (!IsBenchmarkFunctionalOnly()) {
+ b->Arg(512);
+ b->Arg(8192);
+ b->Arg(123456);
+ b->Arg(1234567);
+ }
+}
}
static void BM_BitVectorAppendTrue(benchmark::State& state) {
@@ -72,12 +86,7 @@
benchmark::ClobberMemory();
}
}
-BENCHMARK(BM_BitVectorSet)
- ->Arg(64)
- ->Arg(512)
- ->Arg(8192)
- ->Arg(123456)
- ->Arg(1234567);
+BENCHMARK(BM_BitVectorSet)->Apply(BitVectorArgs);
static void BM_BitVectorClear(benchmark::State& state) {
static constexpr uint32_t kRandomSeed = 42;
@@ -107,12 +116,7 @@
benchmark::ClobberMemory();
}
}
-BENCHMARK(BM_BitVectorClear)
- ->Arg(64)
- ->Arg(512)
- ->Arg(8192)
- ->Arg(123456)
- ->Arg(1234567);
+BENCHMARK(BM_BitVectorClear)->Apply(BitVectorArgs);
static void BM_BitVectorIndexOfNthSet(benchmark::State& state) {
static constexpr uint32_t kRandomSeed = 42;
@@ -142,12 +146,7 @@
pool_idx = (pool_idx + 1) % kPoolSize;
}
}
-BENCHMARK(BM_BitVectorIndexOfNthSet)
- ->Arg(64)
- ->Arg(512)
- ->Arg(8192)
- ->Arg(123456)
- ->Arg(1234567);
+BENCHMARK(BM_BitVectorIndexOfNthSet)->Apply(BitVectorArgs);
static void BM_BitVectorGetNumBitsSet(benchmark::State& state) {
static constexpr uint32_t kRandomSeed = 42;
@@ -175,12 +174,7 @@
}
PERFETTO_CHECK(res == count);
}
-BENCHMARK(BM_BitVectorGetNumBitsSet)
- ->Arg(64)
- ->Arg(512)
- ->Arg(8192)
- ->Arg(123456)
- ->Arg(1234567);
+BENCHMARK(BM_BitVectorGetNumBitsSet)->Apply(BitVectorArgs);
static void BM_BitVectorResize(benchmark::State& state) {
static constexpr uint32_t kRandomSeed = 42;
@@ -239,9 +233,4 @@
benchmark::ClobberMemory();
}
}
-BENCHMARK(BM_BitVectorUpdateSetBits)
- ->Arg(64)
- ->Arg(512)
- ->Arg(8192)
- ->Arg(123456)
- ->Arg(1234567);
+BENCHMARK(BM_BitVectorUpdateSetBits)->Apply(BitVectorArgs);
diff --git a/src/trace_processor/db/column.h b/src/trace_processor/db/column.h
index b2af643..518ac6a 100644
--- a/src/trace_processor/db/column.h
+++ b/src/trace_processor/db/column.h
@@ -142,6 +142,16 @@
PERFETTO_FATAL("For GCC");
}
+ // Sorts |idx| in ascending or descending order (determined by |desc|) based
+ // on the contents of this column.
+ void StableSort(bool desc, std::vector<uint32_t>* idx) const {
+ if (desc) {
+ StableSort<true /* desc */>(idx);
+ } else {
+ StableSort<false /* desc */>(idx);
+ }
+ }
+
// Updates the given RowMap by only keeping rows where this column meets the
// given filter constraint.
void FilterInto(FilterOp op, SqlValue value, RowMap* rm) const {
@@ -580,6 +590,63 @@
}
}
+ template <bool desc>
+ void StableSort(std::vector<uint32_t>* out) const {
+ switch (type_) {
+ case ColumnType::kInt32: {
+ if (IsNullable()) {
+ StableSort<desc, int32_t, true /* is_nullable */>(out);
+ } else {
+ StableSort<desc, int32_t, false /* is_nullable */>(out);
+ }
+ break;
+ }
+ case ColumnType::kUint32: {
+ if (IsNullable()) {
+ StableSort<desc, uint32_t, true /* is_nullable */>(out);
+ } else {
+ StableSort<desc, uint32_t, false /* is_nullable */>(out);
+ }
+ break;
+ }
+ case ColumnType::kInt64: {
+ if (IsNullable()) {
+ StableSort<desc, int64_t, true /* is_nullable */>(out);
+ } else {
+ StableSort<desc, int64_t, false /* is_nullable */>(out);
+ }
+ break;
+ }
+ case ColumnType::kString: {
+ row_map().StableSort(out, [this](uint32_t a_idx, uint32_t b_idx) {
+ auto a_str = GetStringPoolStringAtIdx(a_idx);
+ auto b_str = GetStringPoolStringAtIdx(b_idx);
+ return desc ? b_str < a_str : a_str < b_str;
+ });
+ break;
+ }
+ case ColumnType::kId:
+ row_map().StableSort(out, [](uint32_t a_idx, uint32_t b_idx) {
+ return desc ? b_idx < a_idx : a_idx < b_idx;
+ });
+ }
+ }
+
+ template <bool desc, typename T, bool is_nullable>
+ void StableSort(std::vector<uint32_t>* out) const {
+ const auto& sv = sparse_vector<T>();
+ row_map().StableSort(out, [&sv](uint32_t a_idx, uint32_t b_idx) {
+ if (is_nullable) {
+ auto a_val = sv.Get(a_idx);
+ auto b_val = sv.Get(b_idx);
+ return desc ? b_val < a_val : a_val < b_val;
+ }
+ auto a_val = sv.GetNonNull(a_idx);
+ auto b_val = sv.GetNonNull(b_idx);
+ return desc ? b_val < a_val : a_val < b_val;
+ });
+ }
+
template <typename T>
static ColumnType ToColumnType() {
if (std::is_same<T, uint32_t>::value) {
diff --git a/src/trace_processor/db/row_map.h b/src/trace_processor/db/row_map.h
index 53264da..6cbf045 100644
--- a/src/trace_processor/db/row_map.h
+++ b/src/trace_processor/db/row_map.h
@@ -127,6 +127,9 @@
}
}
+ Iterator(Iterator&&) noexcept = default;
+ Iterator& operator=(Iterator&&) = default;
+
// Forwards the iterator to the next row of the RowMap.
void Next() {
switch (rm_->mode_) {
@@ -190,6 +193,9 @@
}
private:
+ Iterator(const Iterator&) = delete;
+ Iterator& operator=(const Iterator&) = delete;
+
// Only one of the below will be non-null depending on the mode of the
// RowMap.
std::unique_ptr<RangeIterator> range_it_;
@@ -391,6 +397,18 @@
return;
}
+ if (mode_ == Mode::kRange && other.mode_ == Mode::kRange) {
+ // If both RowMaps have ranges, we can just take the smallest intersection
+ // of them as the new RowMap.
+ // This case is important to optimize as it comes up with sorted columns.
+ start_idx_ = std::max(start_idx_, other.start_idx_);
+ end_idx_ = std::min(end_idx_, other.end_idx_);
+
+ if (end_idx_ <= start_idx_)
+ *this = RowMap();
+ return;
+ }
+
// TODO(lalitm): improve efficiency of this if we end up needing it.
RemoveIf([&other](uint32_t row) { return !other.Contains(row); });
}
@@ -434,6 +452,26 @@
}
}
+ template <typename Comparator>
+ void StableSort(std::vector<uint32_t>* out, Comparator c) const {
+ switch (mode_) {
+ case Mode::kRange: {
+ StableSort(out, c, [this](uint32_t off) { return start_idx_ + off; });
+ break;
+ }
+ case Mode::kBitVector: {
+ StableSort(out, c, [this](uint32_t off) {
+ return bit_vector_.IndexOfNthSet(off);
+ });
+ break;
+ }
+ case Mode::kIndexVector: {
+ StableSort(out, c, [this](uint32_t off) { return index_vector_[off]; });
+ break;
+ }
+ }
+ }
+
// Returns the iterator over the rows in this RowMap.
Iterator IterateRows() const { return Iterator(this); }
@@ -530,6 +568,13 @@
}
}
+ template <typename Comparator, typename Indexer>
+ void StableSort(std::vector<uint32_t>* out, Comparator c, Indexer i) const {
+ std::stable_sort(
+ out->begin(), out->end(),
+ [&c, &i](uint32_t a, uint32_t b) { return c(i(a), i(b)); });
+ }
+
RowMap SelectRowsSlow(const RowMap& selector) const;
Mode mode_ = Mode::kRange;
diff --git a/src/trace_processor/db/table.cc b/src/trace_processor/db/table.cc
index 3b22356..d23ba87 100644
--- a/src/trace_processor/db/table.cc
+++ b/src/trace_processor/db/table.cc
@@ -96,17 +96,36 @@
std::vector<uint32_t> idx(size_);
std::iota(idx.begin(), idx.end(), 0);
- // Sort the row indices according to the given order by constraints.
- std::sort(idx.begin(), idx.end(), [this, &od](uint32_t a, uint32_t b) {
- for (const Order& o : od) {
- const Column& col = columns_[o.col_idx];
- int cmp =
- col.Get(a) < col.Get(b) ? -1 : (col.Get(b) < col.Get(a) ? 1 : 0);
- if (cmp != 0)
- return o.desc ? cmp > 0 : cmp < 0;
- }
- return false;
- });
+ // As our data is columnar, it's always more efficient to sort one column
+ // at a time rather than try and sort lexiographically all at once.
+ // To preserve correctness, we need to stably sort the index vector once
+ // for each order by in *reverse* order. Reverse order is important as it
+ // preserves the lexiographical property.
+ //
+ // For example, suppose we have the following:
+ // Table {
+ // Column x;
+ // Column y
+ // Column z;
+ // }
+ //
+ // Then, to sort "y asc, x desc", we could do one of two things:
+ // 1) sort the index vector all at once and on each index, we compare
+ // y then z. This is slow as the data is columnar and we need to
+ // repeatedly branch inside each column.
+ // 2) we can stably sort first on x desc and then sort on y asc. This will
+ // first put all the x in the correct order such that when we sort on
+ // y asc, we will have the correct order of x where y is the same (since
+ // the sort is stable).
+ //
+ // TODO(lalitm): it is possible that we could sort the last constraint (i.e.
+ // the first constraint in the below loop) in a non-stable way. However, this
+ // is more subtle than it appears as we would then need special handling where
+ // there are order bys on a column which is already sorted (e.g. ts, id).
+ // Investigate whether the performance gains from this are worthwhile.
+ for (auto it = od.rbegin(); it != od.rend(); ++it) {
+ columns_[it->col_idx].StableSort(it->desc, &idx);
+ }
// Return a copy of this table with the RowMaps using the computed ordered
// RowMap.
diff --git a/src/trace_processor/db/table.h b/src/trace_processor/db/table.h
index e9410b4..a5e71b9 100644
--- a/src/trace_processor/db/table.h
+++ b/src/trace_processor/db/table.h
@@ -43,6 +43,9 @@
}
}
+ Iterator(Iterator&&) noexcept = default;
+ Iterator& operator=(Iterator&&) = default;
+
// Advances the iterator to the next row of the table.
void Next() {
for (auto& it : its_) {
@@ -60,6 +63,9 @@
}
private:
+ Iterator(const Iterator&) = delete;
+ Iterator& operator=(const Iterator&) = delete;
+
const Table* table_ = nullptr;
std::vector<RowMap::Iterator> its_;
};
diff --git a/src/trace_processor/importers/proto/graphics_event_parser.cc b/src/trace_processor/importers/proto/graphics_event_parser.cc
index f891c83..a1e38cb 100644
--- a/src/trace_processor/importers/proto/graphics_event_parser.cc
+++ b/src/trace_processor/importers/proto/graphics_event_parser.cc
@@ -309,37 +309,95 @@
void GraphicsEventParser::UpdateVulkanMemoryAllocationCounters(
UniquePid upid,
const VulkanMemoryEvent::Decoder& event) {
- if (event.source() == VulkanMemoryEvent::SOURCE_DRIVER) {
- auto allocation_scope = static_cast<VulkanMemoryEvent::AllocationScope>(
- event.allocation_scope());
- if (event.operation() == VulkanMemoryEvent::OP_CREATE) {
- vulkan_driver_memory_counters_[allocation_scope] += event.memory_size();
- } else if (event.operation() == VulkanMemoryEvent::OP_DESTROY) {
- vulkan_driver_memory_counters_[allocation_scope] -= event.memory_size();
- }
- StringId track_id =
- context_->vulkan_memory_tracker->FindAllocationScopeCounterString(
- allocation_scope);
- TrackId track =
- context_->track_tracker->InternProcessCounterTrack(track_id, upid);
- context_->event_tracker->PushCounter(
- event.timestamp(), vulkan_driver_memory_counters_[allocation_scope],
- track);
- } else if (event.source() == VulkanMemoryEvent::SOURCE_BUFFER ||
- event.source() == VulkanMemoryEvent::SOURCE_IMAGE) {
- auto memory_type = static_cast<uint32_t>(event.memory_type());
- if (event.operation() == VulkanMemoryEvent::OP_BIND) {
- vulkan_device_memory_counters_[memory_type] += event.memory_size();
- } else if (event.operation() == VulkanMemoryEvent::OP_DESTROY_BOUND) {
- vulkan_device_memory_counters_[memory_type] -= event.memory_size();
- }
- StringId track_id =
- context_->vulkan_memory_tracker->FindMemoryTypeCounterString(
- memory_type);
- TrackId track =
- context_->track_tracker->InternProcessCounterTrack(track_id, upid);
- context_->event_tracker->PushCounter(
- event.timestamp(), vulkan_device_memory_counters_[memory_type], track);
+ StringId track_id = kNullStringId;
+ TrackId track = UINT32_MAX;
+ auto allocation_scope = VulkanMemoryEvent::SCOPE_UNSPECIFIED;
+ uint32_t memory_type = UINT32_MAX;
+ switch (event.source()) {
+ case VulkanMemoryEvent::SOURCE_DRIVER:
+ allocation_scope = static_cast<VulkanMemoryEvent::AllocationScope>(
+ event.allocation_scope());
+ switch (event.operation()) {
+ case VulkanMemoryEvent::OP_CREATE:
+ vulkan_driver_memory_counters_[allocation_scope] +=
+ event.memory_size();
+ break;
+ case VulkanMemoryEvent::OP_DESTROY:
+ vulkan_driver_memory_counters_[allocation_scope] -=
+ event.memory_size();
+ break;
+ case VulkanMemoryEvent::OP_UNSPECIFIED:
+ case VulkanMemoryEvent::OP_BIND:
+ case VulkanMemoryEvent::OP_DESTROY_BOUND:
+ case VulkanMemoryEvent::OP_ANNOTATIONS:
+ return;
+ }
+ track_id =
+ context_->vulkan_memory_tracker->FindAllocationScopeCounterString(
+ allocation_scope);
+ track =
+ context_->track_tracker->InternProcessCounterTrack(track_id, upid);
+ context_->event_tracker->PushCounter(
+ event.timestamp(), vulkan_driver_memory_counters_[allocation_scope],
+ track);
+ break;
+
+ case VulkanMemoryEvent::SOURCE_DEVICE_MEMORY:
+ memory_type = static_cast<uint32_t>(event.memory_type());
+ switch (event.operation()) {
+ case VulkanMemoryEvent::OP_CREATE:
+ vulkan_device_memory_counters_allocate_[memory_type] +=
+ event.memory_size();
+ break;
+ case VulkanMemoryEvent::OP_DESTROY:
+ vulkan_device_memory_counters_allocate_[memory_type] -=
+ event.memory_size();
+ break;
+ case VulkanMemoryEvent::OP_UNSPECIFIED:
+ case VulkanMemoryEvent::OP_BIND:
+ case VulkanMemoryEvent::OP_DESTROY_BOUND:
+ case VulkanMemoryEvent::OP_ANNOTATIONS:
+ return;
+ }
+ track_id = context_->vulkan_memory_tracker->FindMemoryTypeCounterString(
+ memory_type,
+ VulkanMemoryTracker::DeviceCounterType::kAllocationCounter);
+ track =
+ context_->track_tracker->InternProcessCounterTrack(track_id, upid);
+ context_->event_tracker->PushCounter(
+ event.timestamp(),
+ vulkan_device_memory_counters_allocate_[memory_type], track);
+ break;
+
+ case VulkanMemoryEvent::SOURCE_BUFFER:
+ case VulkanMemoryEvent::SOURCE_IMAGE:
+ memory_type = static_cast<uint32_t>(event.memory_type());
+ switch (event.operation()) {
+ case VulkanMemoryEvent::OP_BIND:
+ vulkan_device_memory_counters_bind_[memory_type] +=
+ event.memory_size();
+ break;
+ case VulkanMemoryEvent::OP_DESTROY_BOUND:
+ vulkan_device_memory_counters_bind_[memory_type] -=
+ event.memory_size();
+ break;
+ case VulkanMemoryEvent::OP_UNSPECIFIED:
+ case VulkanMemoryEvent::OP_CREATE:
+ case VulkanMemoryEvent::OP_DESTROY:
+ case VulkanMemoryEvent::OP_ANNOTATIONS:
+ return;
+ }
+ track_id = context_->vulkan_memory_tracker->FindMemoryTypeCounterString(
+ memory_type, VulkanMemoryTracker::DeviceCounterType::kBindCounter);
+ track =
+ context_->track_tracker->InternProcessCounterTrack(track_id, upid);
+ context_->event_tracker->PushCounter(
+ event.timestamp(), vulkan_device_memory_counters_bind_[memory_type],
+ track);
+ break;
+ case VulkanMemoryEvent::SOURCE_UNSPECIFIED:
+ case VulkanMemoryEvent::SOURCE_DEVICE:
+ return;
}
}
diff --git a/src/trace_processor/importers/proto/graphics_event_parser.h b/src/trace_processor/importers/proto/graphics_event_parser.h
index 489933f..a5f7f4a 100644
--- a/src/trace_processor/importers/proto/graphics_event_parser.h
+++ b/src/trace_processor/importers/proto/graphics_event_parser.h
@@ -77,7 +77,9 @@
ProtoEnumHasher>
vulkan_driver_memory_counters_;
std::unordered_map<uint32_t /*memory_type*/, int64_t /*counter_value*/>
- vulkan_device_memory_counters_;
+ vulkan_device_memory_counters_allocate_;
+ std::unordered_map<uint32_t /*memory_type*/, int64_t /*counter_value*/>
+ vulkan_device_memory_counters_bind_;
// For GpuLog
const StringId gpu_log_track_name_id_;
const StringId gpu_log_scope_id_;
diff --git a/src/trace_processor/importers/proto/heap_graph_module.cc b/src/trace_processor/importers/proto/heap_graph_module.cc
index 50bba45..7216d90 100644
--- a/src/trace_processor/importers/proto/heap_graph_module.cc
+++ b/src/trace_processor/importers/proto/heap_graph_module.cc
@@ -65,6 +65,28 @@
}
}
+// Iterate over a repeated field of varints, independent of whether it is
+// packed or not.
+template <int32_t field_no, typename T, typename F>
+bool ForEachVarInt(const T& decoder, F fn) {
+ auto field = decoder.template at<field_no>();
+ bool parse_error = false;
+ if (field.type() == protozero::proto_utils::ProtoWireType::kLengthDelimited) {
+ // packed repeated
+ auto it = decoder.template GetPackedRepeated<
+ ::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(
+ field_no, &parse_error);
+ for (; it; ++it)
+ fn(*it);
+ } else {
+ // non-packed repeated
+ auto it = decoder.template GetRepeated<uint64_t>(field_no);
+ for (; it; ++it)
+ fn(*it);
+ }
+ return parse_error;
+}
+
} // namespace
void HeapGraphModule::ParseHeapGraph(int64_t ts, protozero::ConstBytes blob) {
@@ -78,21 +100,37 @@
obj.object_id = object.id();
obj.self_size = object.self_size();
obj.type_id = object.type_id();
- auto ref_field_ids_it = object.reference_field_id();
- auto ref_object_ids_it = object.reference_object_id();
- for (; ref_field_ids_it && ref_object_ids_it;
- ++ref_field_ids_it, ++ref_object_ids_it) {
- HeapGraphTracker::SourceObject::Reference ref;
- ref.field_name_id = *ref_field_ids_it;
- ref.owned_object_id = *ref_object_ids_it;
- obj.references.emplace_back(std::move(ref));
+
+ std::vector<uint64_t> field_ids;
+ std::vector<uint64_t> object_ids;
+
+ bool parse_error = ForEachVarInt<
+ protos::pbzero::HeapGraphObject::kReferenceFieldIdFieldNumber>(
+ object, [&field_ids](uint64_t value) { field_ids.push_back(value); });
+
+ if (!parse_error) {
+ parse_error = ForEachVarInt<
+ protos::pbzero::HeapGraphObject::kReferenceObjectIdFieldNumber>(
+ object,
+ [&object_ids](uint64_t value) { object_ids.push_back(value); });
}
- if (ref_field_ids_it || ref_object_ids_it) {
- context_->storage->IncrementIndexedStats(stats::heap_graph_missing_packet,
- static_cast<int>(upid));
+ if (parse_error) {
+ context_->storage->IncrementIndexedStats(
+ stats::heap_graph_malformed_packet, static_cast<int>(upid));
+ break;
+ }
+ if (field_ids.size() != object_ids.size()) {
+ context_->storage->IncrementIndexedStats(
+ stats::heap_graph_malformed_packet, static_cast<int>(upid));
continue;
}
+ for (size_t i = 0; i < field_ids.size(); ++i) {
+ HeapGraphTracker::SourceObject::Reference ref;
+ ref.field_name_id = field_ids[i];
+ ref.owned_object_id = object_ids[i];
+ obj.references.emplace_back(std::move(ref));
+ }
context_->heap_graph_tracker->AddObject(upid, ts, std::move(obj));
}
for (auto it = heap_graph.type_names(); it; ++it) {
@@ -118,8 +156,16 @@
HeapGraphTracker::SourceRoot src_root;
src_root.root_type = context_->storage->InternString(str_view);
- for (auto obj_it = entry.object_ids(); obj_it; ++obj_it)
- src_root.object_ids.emplace_back(*obj_it);
+ bool parse_error =
+ ForEachVarInt<protos::pbzero::HeapGraphRoot::kObjectIdsFieldNumber>(
+ entry, [&src_root](uint64_t value) {
+ src_root.object_ids.emplace_back(value);
+ });
+ if (parse_error) {
+ context_->storage->IncrementIndexedStats(
+ stats::heap_graph_malformed_packet, static_cast<int>(upid));
+ break;
+ }
context_->heap_graph_tracker->AddRoot(upid, ts, std::move(src_root));
}
if (!heap_graph.continued()) {
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker.cc b/src/trace_processor/importers/proto/heap_graph_tracker.cc
index e2d6aef..43ccee0 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker.cc
+++ b/src/trace_processor/importers/proto/heap_graph_tracker.cc
@@ -80,8 +80,11 @@
}
context_->storage->mutable_heap_graph_object_table()->Insert(
{current_upid_, current_ts_, static_cast<int64_t>(obj.object_id),
- static_cast<int64_t>(obj.self_size), -1, 0, -1, 0, it->second,
- base::nullopt});
+ static_cast<int64_t>(obj.self_size), /*retained_size=*/-1,
+ /*unique_retained_size=*/-1, /*reference_set_id=*/-1,
+ /*reachable=*/0, /*type_name=*/it->second,
+ /*deobfuscated_type_name=*/base::nullopt,
+ /*root_type=*/base::nullopt});
int64_t row = context_->storage->heap_graph_object_table().size() - 1;
object_id_to_row_.emplace(obj.object_id, row);
walker_.AddNode(row, obj.self_size);
@@ -95,6 +98,7 @@
int64_t reference_set_id =
context_->storage->heap_graph_reference_table().size();
+ std::set<int64_t> seen_owned;
for (const SourceObject::Reference& ref : obj.references) {
// This is true for unset reference fields.
if (ref.owned_object_id == 0)
@@ -107,7 +111,10 @@
continue;
int64_t owned_row = it->second;
- walker_.AddEdge(owner_row, owned_row);
+ bool inserted;
+ std::tie(std::ignore, inserted) = seen_owned.emplace(owned_row);
+ if (inserted)
+ walker_.AddEdge(owner_row, owned_row);
auto field_name_it = interned_field_names_.find(ref.field_name_id);
if (field_name_it == interned_field_names_.end()) {
@@ -118,7 +125,8 @@
}
StringPool::Id field_name = field_name_it->second;
context_->storage->mutable_heap_graph_reference_table()->Insert(
- {reference_set_id, owner_row, owned_row, field_name});
+ {reference_set_id, owner_row, owned_row, field_name,
+ /*deobfuscated_field_name=*/base::nullopt});
}
context_->storage->mutable_heap_graph_object_table()
->mutable_reference_set_id()
diff --git a/src/trace_processor/importers/proto/heap_graph_walker.cc b/src/trace_processor/importers/proto/heap_graph_walker.cc
index 8655d85..b512571 100644
--- a/src/trace_processor/importers/proto/heap_graph_walker.cc
+++ b/src/trace_processor/importers/proto/heap_graph_walker.cc
@@ -66,8 +66,11 @@
}
void HeapGraphWalker::AddEdge(int64_t owner_row, int64_t owned_row) {
- GetNode(owner_row).children.emplace(&GetNode(owned_row));
- GetNode(owned_row).parents.emplace(&GetNode(owner_row));
+ Node& owner_node = GetNode(owner_row);
+ Node& owned_node = GetNode(owned_row);
+
+ owner_node.children.emplace_back(&owned_node);
+ owned_node.parents.emplace_back(&owner_node);
}
void HeapGraphWalker::MarkRoot(int64_t row) {
@@ -268,23 +271,43 @@
}
void HeapGraphWalker::FindSCC(Node* node) {
- node->node_index = node->lowlink = next_node_index_++;
- node_stack_.push_back(node);
- node->on_stack = true;
- for (Node* child : node->children) {
- PERFETTO_CHECK(child->reachable);
- if (child->node_index == 0) {
- FindSCC(child);
- if (child->lowlink < node->lowlink)
- node->lowlink = child->lowlink;
- } else if (child->on_stack) {
- if (child->node_index < node->lowlink)
+ std::vector<Node*> walk_stack;
+ std::vector<size_t> walk_child;
+
+ walk_stack.emplace_back(node);
+ walk_child.emplace_back(0);
+
+ while (!walk_stack.empty()) {
+ node = walk_stack.back();
+ size_t& child_idx = walk_child.back();
+
+ if (child_idx == 0) {
+ node->node_index = node->lowlink = next_node_index_++;
+ node_stack_.push_back(node);
+ node->on_stack = true;
+ } else {
+ Node* prev_child = node->children[child_idx - 1];
+ if (prev_child->node_index > node->node_index &&
+ prev_child->lowlink < node->lowlink)
+ node->lowlink = prev_child->lowlink;
+ }
+
+ if (child_idx == node->children.size()) {
+ if (node->lowlink == node->node_index)
+ FoundSCC(node);
+ walk_stack.pop_back();
+ walk_child.pop_back();
+ } else {
+ Node* child = node->children[child_idx++];
+ PERFETTO_CHECK(child->reachable);
+ if (child->node_index == 0) {
+ walk_stack.emplace_back(child);
+ walk_child.emplace_back(0);
+ } else if (child->on_stack && child->node_index < node->lowlink) {
node->lowlink = child->node_index;
+ }
}
}
-
- if (node->lowlink == node->node_index)
- FoundSCC(node);
}
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/heap_graph_walker.h b/src/trace_processor/importers/proto/heap_graph_walker.h
index b23f2a3..c05c6df 100644
--- a/src/trace_processor/importers/proto/heap_graph_walker.h
+++ b/src/trace_processor/importers/proto/heap_graph_walker.h
@@ -120,11 +120,8 @@
private:
struct Node {
- // These are sets to conveniently get rid of double edges between nodes.
- // We do not care if an object owns another object via multiple references
- // or only one.
- std::set<Node*> children;
- std::set<Node*> parents;
+ std::vector<Node*> children;
+ std::vector<Node*> parents;
uint64_t self_size = 0;
uint64_t retained_size = 0;
diff --git a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
index 0d184a4..f8c8bdf 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -2266,10 +2266,9 @@
context_.sorter.reset(new TraceSorter(
&context_, std::numeric_limits<int64_t>::max() /*window size*/));
- std::map<ClockTracker::ClockId, int64_t> clock_map;
- clock_map[protos::pbzero::ClockSnapshot::Clock::BOOTTIME] = 0u;
- clock_map[protos::pbzero::ClockSnapshot::Clock::MONOTONIC] = 1000000u;
- clock_->AddSnapshot(clock_map);
+ clock_->AddSnapshot(
+ {{protos::pbzero::ClockSnapshot::Clock::BOOTTIME, 0},
+ {protos::pbzero::ClockSnapshot::Clock::MONOTONIC, 1000000}});
{
auto* packet = trace_.add_packet();
diff --git a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
index 013bc81..44e4266 100644
--- a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
+++ b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
@@ -413,7 +413,7 @@
util::Status ProtoTraceTokenizer::ParseClockSnapshot(ConstBytes blob,
uint32_t seq_id) {
- std::map<ClockTracker::ClockId, int64_t> clock_map;
+ std::vector<ClockTracker::ClockValue> clocks;
protos::pbzero::ClockSnapshot::Decoder evt(blob.data, blob.size);
for (auto it = evt.clocks(); it; ++it) {
protos::pbzero::ClockSnapshot::Clock::Decoder clk(*it);
@@ -427,9 +427,14 @@
}
clock_id = ClockTracker::SeqScopedClockIdToGlobal(seq_id, clk.clock_id());
}
- clock_map[clock_id] = static_cast<int64_t>(clk.timestamp());
+ int64_t unit_multiplier_ns =
+ clk.unit_multiplier_ns()
+ ? static_cast<int64_t>(clk.unit_multiplier_ns())
+ : 1;
+ clocks.emplace_back(clock_id, clk.timestamp(), unit_multiplier_ns,
+ clk.is_incremental());
}
- context_->clock_tracker->AddSnapshot(clock_map);
+ context_->clock_tracker->AddSnapshot(clocks);
return util::OkStatus();
}
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index 14afab1..e93578c 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -212,7 +212,12 @@
} else {
auto args = proc.cmdline();
base::StringView argv0 = args ? *args : base::StringView();
- context_->process_tracker->SetProcessMetadata(pid, ppid, argv0);
+ UniquePid upid =
+ context_->process_tracker->SetProcessMetadata(pid, ppid, argv0);
+ if (proc.has_uid()) {
+ context_->process_tracker->SetProcessUid(
+ upid, static_cast<uint32_t>(proc.uid()));
+ }
}
}
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index 28d6f01..a5b92bc 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -22,7 +22,6 @@
"android/android_cpu_agg.sql",
"android/android_mem.sql",
"android/android_mem_unagg.sql",
- "android/android_process_growth.sql",
"android/android_ion.sql",
"android/android_lmk.sql",
"android/android_powrails.sql",
@@ -35,6 +34,7 @@
"android/java_heap_stats.sql",
"android/process_unagg_mem_view.sql",
"android/process_mem.sql",
+ "android/process_metadata.sql",
"android/mem_stats_priority_breakdown.sql",
"android/span_view_stats.sql",
"android/upid_span_view.sql",
diff --git a/src/trace_processor/metrics/android/android_package_list.sql b/src/trace_processor/metrics/android/android_package_list.sql
index ff9bbfe..7ca9c15 100644
--- a/src/trace_processor/metrics/android/android_package_list.sql
+++ b/src/trace_processor/metrics/android/android_package_list.sql
@@ -15,30 +15,41 @@
--
-- Get distinct packages list
+DROP VIEW IF EXISTS package_arg_ids;
+
CREATE VIEW package_arg_ids AS
SELECT int_value AS arg_set_id
FROM metadata WHERE name = 'android_packages_list';
-- Generate a table mapping package names to their attributes
+DROP VIEW IF EXISTS package_args;
+
CREATE VIEW package_args AS
SELECT arg_set_id, key, string_value, int_value
FROM package_arg_ids JOIN args USING(arg_set_id);
+DROP TABLE IF EXISTS package_list;
+
CREATE TABLE package_list(
package_name TEXT PRIMARY KEY,
uid INT,
- version_code INT
+ version_code INT,
+ debuggable INT
);
INSERT OR REPLACE INTO package_list
-SELECT names.name, uids.uid, versions.version
+SELECT names.name, uids.uid, versions.version, debuggable.is_debug
FROM
(SELECT arg_set_id, string_value name FROM package_args WHERE key = 'name')
AS names
JOIN (SELECT arg_set_id, int_value uid FROM package_args WHERE key = 'uid')
AS uids USING (arg_set_id)
JOIN (SELECT arg_set_id, int_value version FROM package_args WHERE key = 'version_code')
- AS versions USING (arg_set_id);
+ AS versions USING (arg_set_id)
+ JOIN (SELECT arg_set_id, int_value is_debug FROM package_args WHERE key = 'debuggable')
+ AS debuggable USING (arg_set_id);
+
+DROP VIEW IF EXISTS android_package_list_output;
CREATE VIEW android_package_list_output AS
SELECT AndroidPackageList(
diff --git a/src/trace_processor/metrics/android/android_process_growth.sql b/src/trace_processor/metrics/android/android_process_growth.sql
deleted file mode 100644
index 956ce92..0000000
--- a/src/trace_processor/metrics/android/android_process_growth.sql
+++ /dev/null
@@ -1,69 +0,0 @@
---
--- Copyright 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
---
--- https://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.
---
-
-SELECT RUN_METRIC('android/process_mem.sql');
-
-CREATE VIEW malloc_memory_delta AS
-SELECT upid, SUM(size) AS delta
-FROM heap_profile_allocation
-GROUP BY 1;
-
-CREATE VIEW malloc_memory_allocated AS
-SELECT upid, SUM(size) AS total
-FROM heap_profile_allocation
-WHERE size > 0
-GROUP BY 1;
-
-CREATE VIEW anon_and_swap_delta AS
-SELECT DISTINCT
- upid,
- FIRST_VALUE(anon_and_swap_val) OVER upid_window AS start_val,
- LAST_VALUE(anon_and_swap_val) OVER upid_window AS end_val
-FROM anon_and_swap_span
-WINDOW upid_window AS (
- PARTITION BY upid
- ORDER BY ts
- ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
-);
-
-CREATE VIEW process_growth AS
-SELECT
- process.pid AS pid,
- process.name AS process_name,
- CAST(asd.start_val AS BIG INT) AS anon_and_swap_start_value,
- CAST(asd.end_val - asd.start_val AS BIG INT) AS anon_and_swap_change,
- malloc_memory_delta.delta AS malloc_memory_delta,
- malloc_memory_allocated.total AS malloc_memory_total
-FROM anon_and_swap_delta AS asd
-JOIN process USING (upid)
-LEFT JOIN malloc_memory_delta USING (upid)
-LEFT JOIN malloc_memory_allocated USING (upid);
-
-CREATE VIEW instance_metrics_proto AS
-SELECT AndroidProcessGrowth_InstanceMetrics(
- 'pid', pid,
- 'process_name', process_name,
- 'anon_and_swap_start_value', anon_and_swap_start_value,
- 'anon_and_swap_change_bytes', anon_and_swap_change,
- 'malloc_memory_change_bytes', malloc_memory_delta,
- 'malloc_memory_total_allocated_bytes', malloc_memory_total
-) AS instance_metric
-FROM process_growth;
-
-CREATE VIEW android_process_growth_output AS
-SELECT AndroidProcessGrowth(
- 'instance_metrics', (SELECT RepeatedField(instance_metric) FROM instance_metrics_proto)
-);
diff --git a/src/trace_processor/metrics/android/heap_profile_callsites.sql b/src/trace_processor/metrics/android/heap_profile_callsites.sql
index ce2aeb4..f84a8ca 100644
--- a/src/trace_processor/metrics/android/heap_profile_callsites.sql
+++ b/src/trace_processor/metrics/android/heap_profile_callsites.sql
@@ -14,6 +14,8 @@
-- limitations under the License.
--
+SELECT RUN_METRIC('android/process_metadata.sql');
+
CREATE VIEW memory_delta AS
SELECT upid, SUM(size) AS delta
FROM heap_profile_allocation
@@ -216,6 +218,7 @@
SELECT HeapProfileCallsites_InstanceStats(
'pid', process.pid,
'process_name', process.name,
+ 'process', process_metadata.metadata,
'callsites', repeated_callsite_proto,
'profile_delta_bytes', memory_delta.delta,
'profile_total_bytes', memory_total.total
@@ -223,7 +226,8 @@
FROM process_callsite_proto
JOIN memory_total USING (upid)
JOIN memory_delta USING (upid)
-JOIN process USING (upid);
+JOIN process USING (upid)
+JOIN process_metadata USING (upid);
CREATE VIEW heap_profile_callsites_output AS
SELECT HeapProfileCallsites(
diff --git a/src/trace_processor/metrics/android/java_heap_stats.sql b/src/trace_processor/metrics/android/java_heap_stats.sql
index d8f2f34..e5d80b2 100644
--- a/src/trace_processor/metrics/android/java_heap_stats.sql
+++ b/src/trace_processor/metrics/android/java_heap_stats.sql
@@ -14,6 +14,8 @@
-- limitations under the License.
--
+SELECT RUN_METRIC('android/process_metadata.sql');
+
CREATE VIEW total_size_samples AS
SELECT upid, graph_sample_ts, SUM(self_size) AS total_size
FROM heap_graph_object
@@ -43,16 +45,16 @@
CREATE TABLE heap_graph_instance_stats AS
SELECT
upid,
- process.name process_name,
+ process_metadata.metadata AS process_metadata,
RepeatedField(sample_proto) AS sample_protos
-FROM heap_graph_sample_protos JOIN process USING (upid)
+FROM heap_graph_sample_protos JOIN process_metadata USING (upid)
GROUP BY 1, 2;
CREATE VIEW java_heap_stats_output AS
SELECT JavaHeapStats(
'instance_stats', RepeatedField(JavaHeapStats_InstanceStats(
'upid', upid,
- 'process_name', process_name,
+ 'process', process_metadata,
'samples', sample_protos
)))
FROM heap_graph_instance_stats;
diff --git a/src/trace_processor/metrics/android/process_metadata.sql b/src/trace_processor/metrics/android/process_metadata.sql
new file mode 100644
index 0000000..59e86bd
--- /dev/null
+++ b/src/trace_processor/metrics/android/process_metadata.sql
@@ -0,0 +1,31 @@
+--
+-- Copyright 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
+--
+-- https://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.
+--
+
+SELECT RUN_METRIC('android/android_package_list.sql');
+
+DROP TABLE IF EXISTS process_metadata;
+
+CREATE TABLE process_metadata AS
+SELECT
+ process.upid,
+ AndroidProcessMetadata(
+ 'name', process.name,
+ 'uid', uid,
+ 'package_name', plist.package_name,
+ 'apk_version_code', plist.version_code,
+ 'debuggable', plist.debuggable
+ ) AS metadata
+FROM process LEFT JOIN package_list plist USING (uid);
diff --git a/src/trace_processor/metrics/metrics.descriptor.h b/src/trace_processor/metrics/metrics.descriptor.h
index df7696c..9507204 100644
--- a/src/trace_processor/metrics/metrics.descriptor.h
+++ b/src/trace_processor/metrics/metrics.descriptor.h
@@ -12,14 +12,14 @@
// SHA1(tools/gen_binary_descriptors)
// 192b582ae52bb07b3d3ba66a94bcfd3127a5f42f
// SHA1(protos/perfetto/metrics/metrics.proto)
-// 4279eeace6a7d9647e484e65b8265ea211a02b6c
+// fb0504ef20a790f031fc622ba1b9312cb97d67a6
// This is the proto Metrics encoded as a ProtoFileDescriptor to allow
// for reflection without libprotobuf full/non-lite protos.
namespace perfetto {
-constexpr std::array<uint8_t, 10312> kMetricsDescriptor{
+constexpr std::array<uint8_t, 10105> kMetricsDescriptor{
{0x0a, 0x98, 0x03, 0x0a, 0x31, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f,
0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74,
0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
@@ -262,470 +262,460 @@
0x63, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08,
0x6f, 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52,
- 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x02, 0x48, 0x03, 0x0a, 0x90,
- 0x04, 0x0a, 0x34, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x02, 0x48, 0x03, 0x0a, 0xaf,
+ 0x02, 0x0a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65,
0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x70,
- 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x77, 0x74,
- 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72,
- 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
- 0x22, 0xc2, 0x03, 0x0a, 0x14, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
- 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x77, 0x74,
- 0x68, 0x12, 0x60, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
- 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
- 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
- 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61,
- 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x0f,
- 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x73, 0x1a, 0xc7, 0x02, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74,
- 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12,
- 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f,
- 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
- 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6e, 0x6f, 0x6e,
- 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x73, 0x74,
- 0x61, 0x72, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20,
- 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6e, 0x6f, 0x6e, 0x41, 0x6e, 0x64,
- 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x72, 0x74, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x12, 0x3a, 0x0a, 0x1a, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x61,
- 0x6e, 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x6e,
- 0x67, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x16, 0x61, 0x6e, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x53,
- 0x77, 0x61, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x79, 0x74,
- 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63,
- 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e,
- 0x67, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x17, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x4d, 0x65,
- 0x6d, 0x6f, 0x72, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x79,
- 0x74, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x23, 0x6d, 0x61, 0x6c, 0x6c, 0x6f,
- 0x63, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x74, 0x6f, 0x74,
- 0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64,
- 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x1f, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x4d, 0x65, 0x6d, 0x6f,
- 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63,
- 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x02, 0x48,
- 0x03, 0x0a, 0xaf, 0x02, 0x0a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
- 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65,
- 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
- 0x64, 0x2f, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66,
- 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22,
- 0xe5, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x49,
- 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x40, 0x0a, 0x06,
- 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x28, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f,
- 0x69, 0x64, 0x49, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
- 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x52, 0x06, 0x62, 0x75, 0x66, 0x66,
- 0x65, 0x72, 0x1a, 0x8e, 0x01, 0x0a, 0x06, 0x42, 0x75, 0x66, 0x66, 0x65,
- 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a,
- 0x0e, 0x61, 0x76, 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79,
- 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x61,
- 0x76, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12,
- 0x24, 0x0a, 0x0e, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f,
- 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52,
- 0x0c, 0x6d, 0x69, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65,
- 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a,
- 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x01, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79,
- 0x74, 0x65, 0x73, 0x42, 0x02, 0x48, 0x03, 0x0a, 0x95, 0x02, 0x0a, 0x30,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65,
- 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f,
- 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x6c, 0x6d, 0x6b, 0x5f,
- 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xcb, 0x01, 0x0a, 0x10, 0x41, 0x6e,
- 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x4d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f,
- 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
- 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12,
- 0x4e, 0x0a, 0x0c, 0x62, 0x79, 0x5f, 0x6f, 0x6f, 0x6d, 0x5f, 0x73, 0x63,
- 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e,
+ 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x69,
+ 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
+ 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xe5, 0x01, 0x0a,
+ 0x10, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x49, 0x6f, 0x6e, 0x4d,
+ 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x40, 0x0a, 0x06, 0x62, 0x75, 0x66,
+ 0x66, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e,
0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c,
- 0x6d, 0x6b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x42, 0x79, 0x4f,
- 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x52, 0x0a, 0x62, 0x79, 0x4f,
- 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x1a, 0x46, 0x0a, 0x0a, 0x42,
- 0x79, 0x4f, 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x22, 0x0a,
- 0x0d, 0x6f, 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x61,
- 0x64, 0x6a, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6f, 0x6f,
- 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x41, 0x64, 0x6a, 0x12, 0x14, 0x0a,
- 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
- 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x02, 0x48, 0x03, 0x0a,
- 0xf4, 0x02, 0x0a, 0x35, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70,
- 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
- 0x70, 0x6f, 0x77, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x5f, 0x6d, 0x65, 0x74,
+ 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x49,
+ 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x42, 0x75, 0x66,
+ 0x66, 0x65, 0x72, 0x52, 0x06, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x1a,
+ 0x8e, 0x01, 0x0a, 0x06, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x12, 0x12,
+ 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x61, 0x76,
+ 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x61, 0x76, 0x67, 0x53,
+ 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e,
+ 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74,
+ 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x6d, 0x69,
+ 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24,
+ 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62,
+ 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c,
+ 0x6d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73,
+ 0x42, 0x02, 0x48, 0x03, 0x0a, 0x95, 0x02, 0x0a, 0x30, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+ 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64,
+ 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x6c, 0x6d, 0x6b, 0x5f, 0x6d, 0x65, 0x74,
0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70,
0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x73, 0x22, 0xa5, 0x02, 0x0a, 0x11, 0x41, 0x6e, 0x64, 0x72, 0x6f,
- 0x69, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73,
- 0x12, 0x4e, 0x0a, 0x0b, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x72, 0x61,
- 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e,
- 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50,
- 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x50, 0x6f,
- 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0a, 0x70, 0x6f,
- 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x4e, 0x0a, 0x0a,
- 0x45, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x21,
- 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f,
- 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69,
- 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x1d, 0x0a,
- 0x0a, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x5f, 0x75, 0x77, 0x73, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x65, 0x72, 0x67,
- 0x79, 0x55, 0x77, 0x73, 0x1a, 0x70, 0x0a, 0x0a, 0x50, 0x6f, 0x77, 0x65,
- 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
- 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
- 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x0b, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79,
- 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x2d, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
- 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x2e,
- 0x45, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a,
- 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x44, 0x61, 0x74, 0x61, 0x42, 0x02,
- 0x48, 0x03, 0x0a, 0xac, 0x0e, 0x0a, 0x34, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d,
- 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f,
- 0x69, 0x64, 0x2f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x6d,
- 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
- 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xde, 0x0d, 0x0a, 0x14, 0x41, 0x6e, 0x64,
- 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d,
- 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x47, 0x0a, 0x07, 0x73, 0x74, 0x61,
- 0x72, 0x74, 0x75, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d,
- 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
- 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x07, 0x73,
- 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x1a, 0xe0, 0x01, 0x0a, 0x12, 0x54,
- 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x72, 0x65, 0x61,
- 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x75, 0x6e,
- 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x6e, 0x69,
- 0x6e, 0x67, 0x44, 0x75, 0x72, 0x4e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x72,
- 0x75, 0x6e, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x5f,
- 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x72, 0x75,
- 0x6e, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x4e, 0x73, 0x12,
- 0x3f, 0x0a, 0x1c, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75,
- 0x70, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x6c, 0x65, 0x65, 0x70,
- 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x03, 0x52, 0x19, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75,
- 0x70, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x44,
- 0x75, 0x72, 0x4e, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x69, 0x6e, 0x74, 0x65,
- 0x72, 0x72, 0x75, 0x70, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x6c,
- 0x65, 0x65, 0x70, 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72,
- 0x75, 0x70, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x6c, 0x65, 0x65, 0x70,
- 0x44, 0x75, 0x72, 0x4e, 0x73, 0x1a, 0x1e, 0x0a, 0x05, 0x53, 0x6c, 0x69,
- 0x63, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x75, 0x72, 0x4e,
- 0x73, 0x1a, 0xbb, 0x08, 0x0a, 0x0c, 0x54, 0x6f, 0x46, 0x69, 0x72, 0x73,
- 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x75,
- 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05,
- 0x64, 0x75, 0x72, 0x4e, 0x73, 0x12, 0x72, 0x0a, 0x19, 0x6d, 0x61, 0x69,
- 0x6e, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x5f,
- 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
- 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41,
- 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75,
- 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, 0x61, 0x73, 0x6b,
- 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x64, 0x6f,
- 0x77, 0x6e, 0x52, 0x15, 0x6d, 0x61, 0x69, 0x6e, 0x54, 0x68, 0x72, 0x65,
- 0x61, 0x64, 0x42, 0x79, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74,
- 0x65, 0x12, 0x41, 0x0a, 0x1d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70,
- 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x73, 0x70, 0x61,
- 0x77, 0x6e, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50,
- 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x53, 0x70, 0x61, 0x77,
- 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x5f, 0x0a, 0x15,
- 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74,
- 0x79, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x18, 0x04, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
- 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70,
- 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65,
- 0x52, 0x13, 0x74, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69,
- 0x74, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x66, 0x0a,
- 0x19, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69,
- 0x74, 0x79, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6d, 0x61,
- 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70,
+ 0x6f, 0x73, 0x22, 0xcb, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12,
+ 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75,
+ 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x74, 0x6f,
+ 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4e, 0x0a, 0x0c,
+ 0x62, 0x79, 0x5f, 0x6f, 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65,
+ 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x4d,
+ 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x42, 0x79, 0x4f, 0x6f, 0x6d, 0x53,
+ 0x63, 0x6f, 0x72, 0x65, 0x52, 0x0a, 0x62, 0x79, 0x4f, 0x6f, 0x6d, 0x53,
+ 0x63, 0x6f, 0x72, 0x65, 0x1a, 0x46, 0x0a, 0x0a, 0x42, 0x79, 0x4f, 0x6f,
+ 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x6f,
+ 0x6d, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x6a, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6f, 0x6f, 0x6d, 0x53, 0x63,
+ 0x6f, 0x72, 0x65, 0x41, 0x64, 0x6a, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f,
+ 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63,
+ 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x02, 0x48, 0x03, 0x0a, 0xf4, 0x02, 0x0a,
+ 0x35, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66,
+ 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+ 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x70, 0x6f, 0x77,
+ 0x72, 0x61, 0x69, 0x6c, 0x73, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66,
+ 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22,
+ 0xa5, 0x02, 0x0a, 0x11, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50,
+ 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x4e, 0x0a,
+ 0x0b, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x72, 0x61, 0x69, 0x6c, 0x73,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x65,
+ 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x50, 0x6f, 0x77, 0x65, 0x72,
+ 0x52, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0a, 0x70, 0x6f, 0x77, 0x65, 0x72,
+ 0x52, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x4e, 0x0a, 0x0a, 0x45, 0x6e, 0x65,
+ 0x72, 0x67, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x74,
+ 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x6d, 0x73, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73,
+ 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x6e,
+ 0x65, 0x72, 0x67, 0x79, 0x5f, 0x75, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x55, 0x77,
+ 0x73, 0x1a, 0x70, 0x0a, 0x0a, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61,
+ 0x69, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+ 0x4e, 0x0a, 0x0b, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x5f, 0x64, 0x61,
+ 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70,
0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74,
- 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
- 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x41,
- 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x54, 0x68, 0x72, 0x65, 0x61,
- 0x64, 0x4d, 0x61, 0x69, 0x6e, 0x12, 0x5f, 0x0a, 0x15, 0x74, 0x69, 0x6d,
- 0x65, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b,
+ 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x6f,
+ 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x45, 0x6e, 0x65,
+ 0x72, 0x67, 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x65, 0x6e, 0x65,
+ 0x72, 0x67, 0x79, 0x44, 0x61, 0x74, 0x61, 0x42, 0x02, 0x48, 0x03, 0x0a,
+ 0xac, 0x0e, 0x0a, 0x34, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
+ 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65,
+ 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x73, 0x22, 0xde, 0x0d, 0x0a, 0x14, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x12, 0x47, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75,
+ 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x65,
+ 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61,
+ 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53,
+ 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72,
+ 0x74, 0x75, 0x70, 0x1a, 0xe0, 0x01, 0x0a, 0x12, 0x54, 0x61, 0x73, 0x6b,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x64, 0x6f,
+ 0x77, 0x6e, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e,
+ 0x67, 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x44,
+ 0x75, 0x72, 0x4e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x72, 0x75, 0x6e, 0x6e,
+ 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x6e, 0x61,
+ 0x62, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x4e, 0x73, 0x12, 0x3f, 0x0a, 0x1c,
+ 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x69,
+ 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x75,
+ 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19,
+ 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x69,
+ 0x62, 0x6c, 0x65, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x44, 0x75, 0x72, 0x4e,
+ 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75,
+ 0x70, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x6c, 0x65, 0x65, 0x70,
+ 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x17, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74,
+ 0x69, 0x62, 0x6c, 0x65, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x44, 0x75, 0x72,
+ 0x4e, 0x73, 0x1a, 0x1e, 0x0a, 0x05, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x12,
+ 0x15, 0x0a, 0x06, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x75, 0x72, 0x4e, 0x73, 0x1a, 0xbb,
+ 0x08, 0x0a, 0x0c, 0x54, 0x6f, 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72,
+ 0x61, 0x6d, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x75, 0x72, 0x5f, 0x6e,
+ 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x75, 0x72,
+ 0x4e, 0x73, 0x12, 0x72, 0x0a, 0x19, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x74,
+ 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x74, 0x61, 0x73,
+ 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x52,
+ 0x15, 0x6d, 0x61, 0x69, 0x6e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x42,
+ 0x79, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x41,
+ 0x0a, 0x1d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x63,
+ 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x73, 0x70, 0x61, 0x77, 0x6e, 0x65,
+ 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x0d, 0x52, 0x1a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63,
+ 0x65, 0x73, 0x73, 0x65, 0x73, 0x53, 0x70, 0x61, 0x77, 0x6e, 0x65, 0x64,
+ 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x5f, 0x0a, 0x15, 0x74, 0x69, 0x6d,
+ 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x6d,
+ 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f,
0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74,
0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x13, 0x74,
- 0x69, 0x6d, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x70, 0x70, 0x6c, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5b, 0x0a, 0x13, 0x74, 0x69,
+ 0x69, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x4d,
+ 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x66, 0x0a, 0x19, 0x74, 0x69,
0x6d, 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f,
- 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
- 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x11, 0x74, 0x69,
- 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74,
- 0x61, 0x72, 0x74, 0x12, 0x5d, 0x0a, 0x14, 0x74, 0x69, 0x6d, 0x65, 0x5f,
- 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x73,
- 0x75, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
- 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53,
- 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
- 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x12, 0x74, 0x69, 0x6d, 0x65,
- 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x75,
- 0x6d, 0x65, 0x12, 0x5a, 0x0a, 0x12, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63,
- 0x68, 0x6f, 0x72, 0x65, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72,
- 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72,
- 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
- 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72,
- 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c,
- 0x69, 0x63, 0x65, 0x52, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x6f,
- 0x72, 0x65, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72, 0x12, 0x66,
- 0x0a, 0x19, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72,
- 0x65, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x63,
- 0x65, 0x73, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
- 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53,
- 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
- 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65,
- 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50,
- 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x66, 0x0a, 0x19, 0x74, 0x69,
- 0x6d, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74,
- 0x61, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18,
- 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66,
+ 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x18,
+ 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66,
0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74,
0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69,
- 0x63, 0x65, 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x75, 0x72, 0x69,
- 0x6e, 0x67, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x12, 0x4b, 0x0a, 0x23, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f,
- 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x61,
- 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x70, 0x75, 0x5f,
- 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52,
- 0x1e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
- 0x73, 0x54, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x43,
- 0x70, 0x75, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x1a, 0xbb, 0x02, 0x0a, 0x07,
- 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x73,
- 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70,
- 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67,
- 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0b, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d,
- 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
- 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65,
- 0x12, 0x2c, 0x0a, 0x12, 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65, 0x5f, 0x6e,
- 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65,
- 0x4e, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x43,
- 0x0a, 0x1e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x68,
- 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01,
- 0x28, 0x0d, 0x52, 0x1b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79,
- 0x48, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x0e, 0x74,
- 0x6f, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x66, 0x72, 0x61, 0x6d,
- 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x65,
- 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61,
- 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54,
- 0x6f, 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52,
- 0x0c, 0x74, 0x6f, 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d,
- 0x65, 0x42, 0x02, 0x48, 0x03, 0x0a, 0xb7, 0x07, 0x0a, 0x3c, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
- 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e,
- 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x70,
- 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73,
- 0x69, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f,
+ 0x63, 0x65, 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69,
+ 0x76, 0x69, 0x74, 0x79, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x61,
+ 0x69, 0x6e, 0x12, 0x5f, 0x0a, 0x15, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x62,
+ 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x22, 0xe1, 0x06, 0x0a, 0x14, 0x48, 0x65, 0x61, 0x70,
- 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73,
- 0x69, 0x74, 0x65, 0x73, 0x12, 0x5a, 0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x74,
- 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
- 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48,
- 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61,
- 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74,
- 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d, 0x69,
- 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73,
- 0x1a, 0x3e, 0x0a, 0x05, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a,
- 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, 0x70,
- 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67,
- 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x8e, 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x75,
- 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74,
- 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75,
- 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f,
- 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
- 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12,
- 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x63, 0x6f, 0x75,
- 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x64, 0x65,
- 0x6c, 0x74, 0x61, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b,
- 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
- 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x74, 0x61,
- 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0xa6, 0x02, 0x0a, 0x08, 0x43, 0x61,
- 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61,
- 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x68, 0x61,
- 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
- 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
- 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12,
- 0x41, 0x0a, 0x05, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
+ 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53,
+ 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x13, 0x74, 0x69, 0x6d, 0x65,
+ 0x42, 0x69, 0x6e, 0x64, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x12, 0x5b, 0x0a, 0x13, 0x74, 0x69, 0x6d, 0x65, 0x5f,
+ 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x74, 0x61,
+ 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74,
+ 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
+ 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x41,
+ 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74,
+ 0x12, 0x5d, 0x0a, 0x14, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x61, 0x63, 0x74,
+ 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65,
+ 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72,
+ 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c,
+ 0x69, 0x63, 0x65, 0x52, 0x12, 0x74, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x74,
+ 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x12,
+ 0x5a, 0x0a, 0x12, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x6f, 0x72,
+ 0x65, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72, 0x18, 0x09, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+ 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70,
+ 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65,
+ 0x52, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x6f, 0x72, 0x65, 0x6f,
+ 0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72, 0x12, 0x66, 0x0a, 0x19, 0x74,
+ 0x69, 0x6d, 0x65, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x73,
+ 0x74, 0x61, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
+ 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72,
+ 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c,
+ 0x69, 0x63, 0x65, 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x65, 0x66,
+ 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x63,
+ 0x65, 0x73, 0x73, 0x12, 0x66, 0x0a, 0x19, 0x74, 0x69, 0x6d, 0x65, 0x5f,
+ 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74,
+ 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x0b, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
- 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61,
- 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c,
- 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52,
- 0x05, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x4f, 0x0a, 0x0b, 0x73, 0x65,
- 0x6c, 0x66, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x18, 0x04, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65,
- 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c,
- 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74,
- 0x65, 0x72, 0x73, 0x52, 0x0a, 0x73, 0x65, 0x6c, 0x66, 0x41, 0x6c, 0x6c,
- 0x6f, 0x63, 0x73, 0x12, 0x51, 0x0a, 0x0c, 0x63, 0x68, 0x69, 0x6c, 0x64,
- 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70,
- 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73,
- 0x69, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
- 0x73, 0x52, 0x0b, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x41, 0x6c, 0x6c, 0x6f,
- 0x63, 0x73, 0x1a, 0xf2, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61,
- 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03,
- 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70,
- 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
- 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d,
- 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74,
- 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70,
+ 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64,
+ 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d,
+ 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52,
+ 0x16, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x53,
+ 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12,
+ 0x4b, 0x0a, 0x23, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f,
+ 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x61, 0x63, 0x74, 0x69,
+ 0x76, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x1e, 0x6f, 0x74,
+ 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
+ 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x43, 0x70, 0x75, 0x52,
+ 0x61, 0x74, 0x69, 0x6f, 0x1a, 0xbb, 0x02, 0x0a, 0x07, 0x53, 0x74, 0x61,
+ 0x72, 0x74, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72,
+ 0x74, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
+ 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x49, 0x64, 0x12,
+ 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e,
+ 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70,
+ 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21,
+ 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61,
+ 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72,
+ 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a,
+ 0x12, 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f,
+ 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x10, 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65, 0x4e, 0x65, 0x77,
+ 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x43, 0x0a, 0x1e, 0x61,
+ 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x68, 0x6f, 0x73, 0x74,
+ 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x1b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x48, 0x6f, 0x73,
+ 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43,
+ 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x0e, 0x74, 0x6f, 0x5f, 0x66,
+ 0x69, 0x72, 0x73, 0x74, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+ 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75,
+ 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, 0x6f, 0x46, 0x69,
+ 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x0c, 0x74, 0x6f,
+ 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x42, 0x02,
+ 0x48, 0x03, 0x0a, 0xfb, 0x01, 0x0a, 0x36, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d,
+ 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6d,
+ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xab, 0x01, 0x0a, 0x16, 0x41,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
+ 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12,
+ 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e,
+ 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70,
+ 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28,
+ 0x0a, 0x10, 0x61, 0x70, 0x6b, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x0e, 0x61, 0x70, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x62, 0x75,
+ 0x67, 0x67, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x61, 0x62, 0x6c, 0x65,
+ 0x42, 0x02, 0x48, 0x03, 0x0a, 0xb2, 0x08, 0x0a, 0x3c, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+ 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64,
+ 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x70, 0x72,
+ 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69,
+ 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x73, 0x1a, 0x36, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
+ 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6d, 0x65, 0x74, 0x61,
+ 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa4,
+ 0x07, 0x0a, 0x14, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69,
+ 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12,
+ 0x5a, 0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
+ 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x33, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72,
+ 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74,
+ 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53,
+ 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+ 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x1a, 0x3e, 0x0a, 0x05, 0x46,
+ 0x72, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+ 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
+ 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x1a,
+ 0x8e, 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73,
+ 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f,
+ 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74,
+ 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a,
+ 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61,
+ 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65,
+ 0x6c, 0x74, 0x61, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x03, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x43, 0x6f,
+ 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x6c, 0x74, 0x61,
+ 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x42, 0x79, 0x74, 0x65, 0x73,
+ 0x1a, 0xa6, 0x02, 0x0a, 0x08, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74,
+ 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x03, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a,
+ 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65,
+ 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x41, 0x0a, 0x05, 0x66, 0x72,
+ 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
+ 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66,
+ 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73,
+ 0x2e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x05, 0x66, 0x72, 0x61, 0x6d,
+ 0x65, 0x12, 0x4f, 0x0a, 0x0b, 0x73, 0x65, 0x6c, 0x66, 0x5f, 0x61, 0x6c,
+ 0x6c, 0x6f, 0x63, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e,
+ 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f,
+ 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65,
+ 0x73, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0a,
+ 0x73, 0x65, 0x6c, 0x66, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x12, 0x51,
+ 0x0a, 0x0c, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x6f,
+ 0x63, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70,
0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69,
0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e,
- 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x52, 0x09, 0x63, 0x61,
- 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x70,
- 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61,
- 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x11, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x6c,
- 0x74, 0x61, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x70,
- 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c,
- 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x11, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x6f, 0x74,
- 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x02, 0x48, 0x03, 0x0a,
- 0x8c, 0x02, 0x0a, 0x32, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70,
- 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
- 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66,
- 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22,
- 0xc0, 0x01, 0x0a, 0x12, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50,
- 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x47,
- 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
- 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41,
- 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67,
- 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67,
- 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x1a,
- 0x61, 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x21,
- 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61,
- 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61,
- 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a,
- 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03,
- 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x03, 0x52, 0x0b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f,
- 0x64, 0x65, 0x42, 0x02, 0x48, 0x03, 0x0a, 0x80, 0x02, 0x0a, 0x39, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61,
- 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x75, 0x6e, 0x73, 0x79, 0x6d,
- 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x6d,
- 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65,
- 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x73, 0x22, 0xad, 0x01, 0x0a, 0x12, 0x55, 0x6e, 0x73, 0x79, 0x6d, 0x62,
- 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
- 0x12, 0x41, 0x0a, 0x06, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
- 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x55,
- 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x46,
- 0x72, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52,
- 0x06, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x54, 0x0a, 0x05, 0x46,
- 0x72, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75,
- 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f,
- 0x64, 0x75, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x75, 0x69, 0x6c,
- 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
- 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61,
- 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x02, 0x48,
- 0x03, 0x0a, 0xa4, 0x03, 0x0a, 0x35, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0b, 0x63, 0x68,
+ 0x69, 0x6c, 0x64, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x1a, 0xb5, 0x02,
+ 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74,
+ 0x61, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x21, 0x0a,
+ 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d,
+ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f,
+ 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x07,
+ 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63,
+ 0x65, 0x73, 0x73, 0x12, 0x4c, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x73,
+ 0x69, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e,
+ 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f,
+ 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65,
+ 0x73, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x52, 0x09,
+ 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x2e, 0x0a,
+ 0x13, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x6c,
+ 0x74, 0x61, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x44,
+ 0x65, 0x6c, 0x74, 0x61, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2e, 0x0a,
+ 0x13, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x6f, 0x74,
+ 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54,
+ 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x02, 0x48,
+ 0x03, 0x0a, 0x8c, 0x02, 0x0a, 0x32, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65,
0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
- 0x64, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f,
- 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
- 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xd5, 0x02, 0x0a, 0x0d, 0x4a, 0x61, 0x76,
- 0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x53,
- 0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73,
- 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c,
- 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61,
- 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61,
- 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d, 0x69, 0x6e,
- 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x1a,
- 0x65, 0x0a, 0x06, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x0e, 0x0a,
- 0x02, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x74,
- 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x69,
- 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x68, 0x65,
- 0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65,
- 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x70,
- 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
- 0x11, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x65,
- 0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x1a, 0x87, 0x01, 0x0a, 0x0d, 0x49,
- 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73,
- 0x12, 0x12, 0x0a, 0x04, 0x75, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0d, 0x52, 0x04, 0x75, 0x70, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c,
- 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63,
- 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x07, 0x73,
- 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x25, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x48,
- 0x65, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x53, 0x61, 0x6d,
- 0x70, 0x6c, 0x65, 0x52, 0x07, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73,
- 0x42, 0x02, 0x48, 0x03, 0x0a, 0xed, 0x10, 0x0a, 0x25, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
- 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x6d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f,
+ 0x64, 0x2f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x69,
+ 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65,
+ 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x73, 0x22, 0xc0, 0x01, 0x0a, 0x12, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74,
+ 0x12, 0x47, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b,
+ 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50, 0x61, 0x63, 0x6b,
+ 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
+ 0x73, 0x1a, 0x61, 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
+ 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
+ 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12,
+ 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x03, 0x52, 0x0b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x43, 0x6f, 0x64, 0x65, 0x42, 0x02, 0x48, 0x03, 0x0a, 0x80, 0x02, 0x0a,
+ 0x39, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66,
+ 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+ 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x75, 0x6e, 0x73,
+ 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x66, 0x72,
+ 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f,
0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x1a, 0x31, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f,
- 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
- 0x2f, 0x62, 0x61, 0x74, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x70, 0x72, 0x6f, 0x74,
+ 0x74, 0x6f, 0x73, 0x22, 0xad, 0x01, 0x0a, 0x12, 0x55, 0x6e, 0x73, 0x79,
+ 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x46, 0x72, 0x61, 0x6d,
+ 0x65, 0x73, 0x12, 0x41, 0x0a, 0x06, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x55, 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65,
+ 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x46, 0x72, 0x61, 0x6d,
+ 0x65, 0x52, 0x06, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x54, 0x0a,
+ 0x05, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f,
+ 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
+ 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x18, 0x0a,
+ 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42,
+ 0x02, 0x48, 0x03, 0x0a, 0xfc, 0x03, 0x0a, 0x35, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f,
0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72,
- 0x6f, 0x69, 0x64, 0x2f, 0x63, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
- 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e,
- 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x65,
- 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x36,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65,
- 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f,
- 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x6d, 0x65, 0x6d, 0x5f,
- 0x75, 0x6e, 0x61, 0x67, 0x67, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x34, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x69, 0x64, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x68, 0x65, 0x61,
+ 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x1a, 0x36, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f,
0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72,
0x6f, 0x69, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f,
- 0x67, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x22, 0xf5, 0x02, 0x0a, 0x0d, 0x4a, 0x61, 0x76, 0x61, 0x48,
+ 0x65, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x53, 0x0a, 0x0e,
+ 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61,
+ 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x73, 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x53,
+ 0x74, 0x61, 0x74, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
+ 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d, 0x69, 0x6e, 0x73, 0x74,
+ 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x1a, 0x65, 0x0a,
+ 0x06, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x74,
+ 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x74, 0x73, 0x12,
+ 0x1b, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x68, 0x65, 0x61, 0x70,
+ 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65, 0x61, 0x63,
+ 0x68, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73,
+ 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x72,
+ 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x70,
+ 0x53, 0x69, 0x7a, 0x65, 0x1a, 0xa7, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x73,
+ 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x12,
+ 0x0a, 0x04, 0x75, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
+ 0x52, 0x04, 0x75, 0x70, 0x69, 0x64, 0x12, 0x41, 0x0a, 0x07, 0x70, 0x72,
+ 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x27, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61,
+ 0x64, 0x61, 0x74, 0x61, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
+ 0x73, 0x12, 0x3f, 0x0a, 0x07, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73,
+ 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61,
+ 0x74, 0x73, 0x2e, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x07, 0x73,
+ 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x42, 0x02, 0x48, 0x03, 0x0a, 0xe0,
+ 0x0f, 0x0a, 0x25, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65,
+ 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,
+ 0x63, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+ 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x1a, 0x31, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+ 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x62, 0x61, 0x74, 0x74, 0x5f,
+ 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x1a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x63, 0x70,
+ 0x75, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x1a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
+ 0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x36, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x2f, 0x6d, 0x65, 0x6d, 0x5f, 0x75, 0x6e, 0x61, 0x67, 0x67, 0x5f,
+ 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x1a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x65, 0x72,
0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x69, 0x6f,
@@ -782,7 +772,7 @@
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x78,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x69, 0x64, 0x78, 0x12,
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x80, 0x09,
+ 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa9, 0x08,
0x0a, 0x0c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69,
0x63, 0x73, 0x12, 0x48, 0x0a, 0x0c, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
0x64, 0x5f, 0x62, 0x61, 0x74, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
@@ -817,69 +807,62 @@
0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
0x4c, 0x69, 0x73, 0x74, 0x52, 0x12, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74,
- 0x12, 0x5b, 0x0a, 0x16, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f,
- 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x77,
- 0x74, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70,
- 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72,
- 0x6f, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x52,
- 0x14, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63,
- 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x12, 0x42, 0x0a,
- 0x0b, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x69, 0x6f, 0x6e,
- 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72,
- 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
- 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x49, 0x6f, 0x6e, 0x4d,
- 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x0a, 0x61, 0x6e, 0x64, 0x72, 0x6f,
- 0x69, 0x64, 0x49, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x0b, 0x61, 0x6e, 0x64,
- 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x6c, 0x6d, 0x6b, 0x18, 0x08, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
- 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64,
- 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x4d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x52, 0x0a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d,
- 0x6b, 0x12, 0x4d, 0x0a, 0x10, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
- 0x5f, 0x70, 0x6f, 0x77, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x07, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
- 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61,
- 0x69, 0x6c, 0x73, 0x52, 0x0f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
- 0x50, 0x6f, 0x77, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x0f,
- 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x72,
- 0x74, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e,
+ 0x12, 0x42, 0x0a, 0x0b, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f,
+ 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e,
0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53,
- 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
- 0x52, 0x0e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61,
- 0x72, 0x74, 0x75, 0x70, 0x12, 0x5b, 0x0a, 0x16, 0x68, 0x65, 0x61, 0x70,
- 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x61, 0x6c,
- 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x25, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50,
- 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69,
- 0x74, 0x65, 0x73, 0x52, 0x14, 0x68, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f,
- 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65,
- 0x73, 0x12, 0x45, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x6d,
- 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63,
- 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d, 0x74,
- 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
- 0x12, 0x54, 0x0a, 0x13, 0x75, 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c,
- 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18,
- 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x65, 0x72, 0x66,
+ 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x49,
+ 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x0a, 0x61, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x49, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x0b,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x6c, 0x6d, 0x6b, 0x18,
+ 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72, 0x66,
0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
- 0x55, 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64,
- 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x12, 0x75, 0x6e, 0x73, 0x79,
- 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x46, 0x72, 0x61, 0x6d,
- 0x65, 0x73, 0x12, 0x46, 0x0a, 0x0f, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x68,
- 0x65, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x11, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4a, 0x61,
- 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52,
- 0x0d, 0x6a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61,
- 0x74, 0x73, 0x2a, 0x06, 0x08, 0xc2, 0x03, 0x10, 0xf4, 0x03, 0x2a, 0x06,
- 0x08, 0xf4, 0x03, 0x10, 0xe9, 0x07, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05,
- 0x4a, 0x04, 0x08, 0x0d, 0x10, 0x0e, 0x4a, 0x04, 0x08, 0x0e, 0x10, 0x0f,
- 0x42, 0x02, 0x48, 0x03}};
+ 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x4d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x52, 0x0a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x4c, 0x6d, 0x6b, 0x12, 0x4d, 0x0a, 0x10, 0x61, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x5f, 0x70, 0x6f, 0x77, 0x72, 0x61, 0x69, 0x6c, 0x73,
+ 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x65,
+ 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0f, 0x61, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x12,
+ 0x4e, 0x0a, 0x0f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x73,
+ 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x25, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74,
+ 0x72, 0x69, 0x63, 0x52, 0x0e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x5b, 0x0a, 0x16, 0x68,
+ 0x65, 0x61, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f,
+ 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x18, 0x10, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+ 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65,
+ 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c,
+ 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x52, 0x14, 0x68, 0x65, 0x61, 0x70,
+ 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73,
+ 0x69, 0x74, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x63,
+ 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+ 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54,
+ 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
+ 0x52, 0x0d, 0x74, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x13, 0x75, 0x6e, 0x73, 0x79, 0x6d,
+ 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x6d,
+ 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69,
+ 0x7a, 0x65, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x12, 0x75,
+ 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x46,
+ 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x46, 0x0a, 0x0f, 0x6a, 0x61, 0x76,
+ 0x61, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73,
+ 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61,
+ 0x74, 0x73, 0x52, 0x0d, 0x6a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70,
+ 0x53, 0x74, 0x61, 0x74, 0x73, 0x2a, 0x06, 0x08, 0xc2, 0x03, 0x10, 0xf4,
+ 0x03, 0x2a, 0x06, 0x08, 0xf4, 0x03, 0x10, 0xe9, 0x07, 0x4a, 0x04, 0x08,
+ 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x0a, 0x10, 0x0b, 0x4a, 0x04, 0x08,
+ 0x0d, 0x10, 0x0e, 0x4a, 0x04, 0x08, 0x0e, 0x10, 0x0f, 0x42, 0x02, 0x48,
+ 0x03}};
} // namespace perfetto
diff --git a/src/trace_processor/process_table.cc b/src/trace_processor/process_table.cc
index adc9d1e..a25c0fa 100644
--- a/src/trace_processor/process_table.cc
+++ b/src/trace_processor/process_table.cc
@@ -47,6 +47,7 @@
SqliteTable::Column(Column::kEndTs, "end_ts", SqlValue::Type::kLong),
SqliteTable::Column(Column::kParentUpid, "parent_upid",
SqlValue::Type::kLong),
+ SqliteTable::Column(Column::kUid, "uid", SqlValue::Type::kLong),
},
{Column::kUpid});
return util::OkStatus();
@@ -73,7 +74,8 @@
: SqliteTable::Cursor(table), storage_(table->storage_) {}
int ProcessTable::Cursor::Filter(const QueryConstraints& qc,
- sqlite3_value** argv) {
+ sqlite3_value** argv,
+ FilterHistory) {
min_ = 0;
max_ = static_cast<uint32_t>(storage_->process_count());
desc_ = false;
@@ -147,6 +149,14 @@
}
break;
}
+ case Column::kUid: {
+ if (process.uid.has_value()) {
+ sqlite3_result_int64(context, process.uid.value());
+ } else {
+ sqlite3_result_null(context);
+ }
+ break;
+ }
default:
PERFETTO_FATAL("Unknown column %d", N);
break;
diff --git a/src/trace_processor/process_table.h b/src/trace_processor/process_table.h
index c4c1ed5..7e661a6 100644
--- a/src/trace_processor/process_table.h
+++ b/src/trace_processor/process_table.h
@@ -36,14 +36,17 @@
kPid = 2,
kStartTs = 3,
kEndTs = 4,
- kParentUpid = 5
+ kParentUpid = 5,
+ kUid = 6
};
class Cursor : public SqliteTable::Cursor {
public:
Cursor(ProcessTable*);
// Implementation of Table::Cursor.
- int Filter(const QueryConstraints&, sqlite3_value**) override;
+ int Filter(const QueryConstraints&,
+ sqlite3_value**,
+ FilterHistory) override;
int Next() override;
int Eof() override;
int Column(sqlite3_context*, int N) override;
diff --git a/src/trace_processor/process_tracker.cc b/src/trace_processor/process_tracker.cc
index e9c0335..1ccc4b7 100644
--- a/src/trace_processor/process_tracker.cc
+++ b/src/trace_processor/process_tracker.cc
@@ -194,6 +194,10 @@
return upid;
}
+void ProcessTracker::SetProcessUid(UniquePid upid, uint32_t uid) {
+ context_->storage->GetMutableProcess(upid)->uid = uid;
+}
+
void ProcessTracker::SetProcessNameIfUnset(UniquePid upid,
StringId process_name_id) {
TraceStorage::Process* process = context_->storage->GetMutableProcess(upid);
diff --git a/src/trace_processor/process_tracker.h b/src/trace_processor/process_tracker.h
index 7c7ea55..985212b 100644
--- a/src/trace_processor/process_tracker.h
+++ b/src/trace_processor/process_tracker.h
@@ -91,6 +91,9 @@
base::Optional<uint32_t> ppid,
base::StringView name);
+ // Sets the process user id.
+ void SetProcessUid(UniquePid upid, uint32_t uid);
+
// Assigns the given name to the process identified by |upid| if it does not
// have a name yet.
void SetProcessNameIfUnset(UniquePid upid, StringId process_name_id);
diff --git a/src/trace_processor/span_join_operator_table.cc b/src/trace_processor/span_join_operator_table.cc
index 931289c..6067483 100644
--- a/src/trace_processor/span_join_operator_table.cc
+++ b/src/trace_processor/span_join_operator_table.cc
@@ -169,8 +169,14 @@
return std::unique_ptr<SpanJoinOperatorTable::Cursor>(new Cursor(this, db_));
}
-int SpanJoinOperatorTable::BestIndex(const QueryConstraints&, BestIndexInfo*) {
+int SpanJoinOperatorTable::BestIndex(const QueryConstraints& qc,
+ BestIndexInfo* info) {
// TODO(lalitm): figure out cost estimation.
+ const auto& ob = qc.order_by();
+ if (ob.size() == 1 && ob.front().iColumn == Column::kTimestamp &&
+ !ob.front().desc) {
+ info->sqlite_omit_order_by = true;
+ }
return SQLITE_OK;
}
@@ -187,8 +193,7 @@
continue;
if (col_name == kTsColumnName || col_name == kDurColumnName) {
- // We don't support constraints on ts or duration in the child tables.
- PERFETTO_DFATAL("ts or duration constraints on child tables");
+ // Allow SQLite handle any constraints on ts or duration.
continue;
}
auto op = sqlite_utils::OpToString(cs.op);
@@ -278,7 +283,8 @@
table_(table) {}
int SpanJoinOperatorTable::Cursor::Filter(const QueryConstraints& qc,
- sqlite3_value** argv) {
+ sqlite3_value** argv,
+ FilterHistory) {
int err = t1_.Initialize(qc, argv);
if (err != SQLITE_OK)
return err;
diff --git a/src/trace_processor/span_join_operator_table.h b/src/trace_processor/span_join_operator_table.h
index eb96161..dfc4439 100644
--- a/src/trace_processor/span_join_operator_table.h
+++ b/src/trace_processor/span_join_operator_table.h
@@ -227,7 +227,9 @@
Cursor(SpanJoinOperatorTable*, sqlite3* db);
~Cursor() override = default;
- int Filter(const QueryConstraints& qc, sqlite3_value** argv) override;
+ int Filter(const QueryConstraints& qc,
+ sqlite3_value** argv,
+ FilterHistory) override;
int Column(sqlite3_context* context, int N) override;
int Next() override;
int Eof() override;
diff --git a/src/trace_processor/sql_stats_table.cc b/src/trace_processor/sql_stats_table.cc
index 0d434a0..11da41b 100644
--- a/src/trace_processor/sql_stats_table.cc
+++ b/src/trace_processor/sql_stats_table.cc
@@ -66,7 +66,9 @@
SqlStatsTable::Cursor::~Cursor() = default;
-int SqlStatsTable::Cursor::Filter(const QueryConstraints&, sqlite3_value**) {
+int SqlStatsTable::Cursor::Filter(const QueryConstraints&,
+ sqlite3_value**,
+ FilterHistory) {
*this = Cursor(table_);
num_rows_ = storage_->sql_stats().size();
return SQLITE_OK;
diff --git a/src/trace_processor/sql_stats_table.h b/src/trace_processor/sql_stats_table.h
index 0ff06a7..7793f2e 100644
--- a/src/trace_processor/sql_stats_table.h
+++ b/src/trace_processor/sql_stats_table.h
@@ -47,7 +47,9 @@
~Cursor() override;
// Implementation of SqliteTable::Cursor.
- int Filter(const QueryConstraints&, sqlite3_value**) override;
+ int Filter(const QueryConstraints&,
+ sqlite3_value**,
+ FilterHistory) override;
int Next() override;
int Eof() override;
int Column(sqlite3_context*, int N) override;
diff --git a/src/trace_processor/sqlite/db_sqlite_table.cc b/src/trace_processor/sqlite/db_sqlite_table.cc
index 8b3dfc8..698f5f5 100644
--- a/src/trace_processor/sqlite/db_sqlite_table.cc
+++ b/src/trace_processor/sqlite/db_sqlite_table.cc
@@ -119,6 +119,34 @@
return SQLITE_OK;
}
+int DbSqliteTable::ModifyConstraints(QueryConstraints* qc) {
+ using C = QueryConstraints::Constraint;
+
+ // Reorder constraints to consider the constraints on columns which are
+ // cheaper to filter first.
+ auto* cs = qc->mutable_constraints();
+ std::sort(cs->begin(), cs->end(), [this](const C& a, const C& b) {
+ uint32_t a_idx = static_cast<uint32_t>(a.column);
+ uint32_t b_idx = static_cast<uint32_t>(b.column);
+ const auto& a_col = table_->GetColumn(a_idx);
+ const auto& b_col = table_->GetColumn(b_idx);
+
+ // Id columns are always very cheap to filter on so try and get them
+ // first.
+ if (a_col.IsId() && !b_col.IsId())
+ return true;
+
+ // Sorted columns are also quite cheap to filter so order them after
+ // any id columns.
+ if (a_col.IsSorted() && !b_col.IsSorted())
+ return true;
+
+ // TODO(lalitm): introduce more orderings here based on empirical data.
+ return false;
+ });
+ return SQLITE_OK;
+}
+
double DbSqliteTable::EstimateCost(const QueryConstraints& qc) {
// Currently our cost estimation algorithm is quite simplistic but is good
// enough for the simplest cases.
@@ -158,11 +186,30 @@
: SqliteTable::Cursor(table), initial_db_table_(table->table_) {}
int DbSqliteTable::Cursor::Filter(const QueryConstraints& qc,
- sqlite3_value** argv) {
+ sqlite3_value** argv,
+ FilterHistory history) {
// Clear out the iterator before filtering to ensure the destructor is run
// before the table's destructor.
iterator_ = base::nullopt;
+ if (history == FilterHistory::kSame && qc.constraints().size() == 1 &&
+ sqlite_utils::IsOpEq(qc.constraints().front().op)) {
+ // If we've seen the same constraint set with a single equality constraint
+ // more than |kRepeatedThreshold| times, we assume we will see it more
+ // in the future and thus cache a table sorted on the column. That way,
+ // future equality constraints can binary search for the value instead of
+ // doing a full table scan.
+ constexpr uint32_t kRepeatedThreshold = 3;
+ if (!sorted_cache_table_ && repeated_cache_count_++ > kRepeatedThreshold) {
+ const auto& c = qc.constraints().front();
+ uint32_t col = static_cast<uint32_t>(c.column);
+ sorted_cache_table_ = initial_db_table_->Sort({Order{col, false}});
+ }
+ } else {
+ sorted_cache_table_ = base::nullopt;
+ repeated_cache_count_ = 0;
+ }
+
// We reuse this vector to reduce memory allocations on nested subqueries.
constraints_.resize(qc.constraints().size());
for (size_t i = 0; i < qc.constraints().size(); ++i) {
@@ -183,7 +230,11 @@
orders_[i] = Order{col, static_cast<bool>(ob.desc)};
}
- db_table_ = initial_db_table_->Filter(constraints_).Sort(orders_);
+ // Try and use the sorted cache table (if it exists) to speed up the sorting.
+ // Otherwise, just use the original table.
+ auto* source =
+ sorted_cache_table_ ? &*sorted_cache_table_ : &*initial_db_table_;
+ db_table_ = source->Filter(constraints_).Sort(orders_);
iterator_ = db_table_->IterateRows();
return SQLITE_OK;
diff --git a/src/trace_processor/sqlite/db_sqlite_table.h b/src/trace_processor/sqlite/db_sqlite_table.h
index 6afcbfe..f6adf0f 100644
--- a/src/trace_processor/sqlite/db_sqlite_table.h
+++ b/src/trace_processor/sqlite/db_sqlite_table.h
@@ -30,18 +30,35 @@
public:
explicit Cursor(DbSqliteTable* table);
+ Cursor(Cursor&&) noexcept = default;
+ Cursor& operator=(Cursor&&) = default;
+
// Implementation of SqliteTable::Cursor.
- int Filter(const QueryConstraints& qc, sqlite3_value** argv) override;
+ int Filter(const QueryConstraints& qc,
+ sqlite3_value** argv,
+ FilterHistory) override;
int Next() override;
int Eof() override;
int Column(sqlite3_context*, int N) override;
private:
+ Cursor(const Cursor&) = delete;
+ Cursor& operator=(const Cursor&) = delete;
+
const Table* initial_db_table_ = nullptr;
base::Optional<Table> db_table_;
base::Optional<Table::Iterator> iterator_;
+ // Stores a sorted version of |db_table_| sorted on a repeated equals
+ // constraint. This allows speeding up repeated subqueries in joins
+ // significantly.
+ base::Optional<Table> sorted_cache_table_;
+
+ // Stores the count of repeated equality queries to decide whether it is
+ // wortwhile to sort |db_table_| to create |sorted_cache_table_|.
+ uint32_t repeated_cache_count_ = 0;
+
std::vector<Constraint> constraints_;
std::vector<Order> orders_;
};
@@ -58,6 +75,7 @@
const char* const*,
SqliteTable::Schema*) override final;
std::unique_ptr<SqliteTable::Cursor> CreateCursor() override;
+ int ModifyConstraints(QueryConstraints*) override;
int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
private:
diff --git a/src/trace_processor/sqlite/sqlite_table.cc b/src/trace_processor/sqlite/sqlite_table.cc
index 512d672..8456ad2 100644
--- a/src/trace_processor/sqlite/sqlite_table.cc
+++ b/src/trace_processor/sqlite/sqlite_table.cc
@@ -130,9 +130,7 @@
return SQLITE_READONLY;
}
-const QueryConstraints& SqliteTable::ParseConstraints(int idxNum,
- const char* idxStr,
- int argc) {
+bool SqliteTable::ReadConstraints(int idxNum, const char* idxStr, int argc) {
bool cache_hit = true;
if (idxNum != qc_hash_) {
qc_cache_ = QueryConstraints::FromString(idxStr);
@@ -143,7 +141,7 @@
PERFETTO_LOG("[%s::ParseConstraints] constraints=%s argc=%d cache_hit=%d",
name_.c_str(), idxStr, argc, cache_hit);
}
- return qc_cache_;
+ return cache_hit;
}
SqliteTable::Cursor::Cursor(SqliteTable* table) : table_(table) {
diff --git a/src/trace_processor/sqlite/sqlite_table.h b/src/trace_processor/sqlite/sqlite_table.h
index c53baaf..2564ebc 100644
--- a/src/trace_processor/sqlite/sqlite_table.h
+++ b/src/trace_processor/sqlite/sqlite_table.h
@@ -74,13 +74,28 @@
// API for subclasses to implement.
class Cursor : public sqlite3_vtab_cursor {
public:
+ // Enum for the history of calls to Filter.
+ enum class FilterHistory : uint32_t {
+ // Indicates that constraint set passed is the different to the
+ // previous Filter call.
+ kDifferent = 0,
+
+ // Indicates that the constraint set passed is the same as the previous
+ // Filter call.
+ // This can be useful for subclasses to perform optimizations on repeated
+ // nested subqueries.
+ kSame = 1,
+ };
+
Cursor(SqliteTable* table);
virtual ~Cursor();
// Methods to be implemented by derived table classes.
// Called to intialise the cursor with the constraints of the query.
- virtual int Filter(const QueryConstraints& qc, sqlite3_value**) = 0;
+ virtual int Filter(const QueryConstraints& qc,
+ sqlite3_value**,
+ FilterHistory) = 0;
// Called to forward the cursor to the next row in the table.
virtual int Next() = 0;
@@ -233,11 +248,14 @@
module->xBestIndex = [](sqlite3_vtab* t, sqlite3_index_info* i) {
return static_cast<TTable*>(t)->BestIndexInternal(i);
};
- module->xFilter = [](sqlite3_vtab_cursor* c, int i, const char* s, int a,
+ module->xFilter = [](sqlite3_vtab_cursor* vc, int i, const char* s, int a,
sqlite3_value** v) {
- const auto& qc =
- static_cast<Cursor*>(c)->table_->ParseConstraints(i, s, a);
- return static_cast<TCursor*>(c)->Filter(qc, v);
+ auto* c = static_cast<Cursor*>(vc);
+ bool is_cached = c->table_->ReadConstraints(i, s, a);
+
+ auto history = is_cached ? Cursor::FilterHistory::kSame
+ : Cursor::FilterHistory::kDifferent;
+ return static_cast<TCursor*>(c)->Filter(c->table_->qc_cache_, v, history);
};
module->xNext = [](sqlite3_vtab_cursor* c) {
return static_cast<TCursor*>(c)->Next();
@@ -315,9 +333,7 @@
};
}
- const QueryConstraints& ParseConstraints(int idxNum,
- const char* idxStr,
- int argc);
+ bool ReadConstraints(int idxNum, const char* idxStr, int argc);
// Overriden functions from sqlite3_vtab.
int OpenInternal(sqlite3_vtab_cursor**);
diff --git a/src/trace_processor/stats_table.cc b/src/trace_processor/stats_table.cc
index 8881897..ab4599a 100644
--- a/src/trace_processor/stats_table.cc
+++ b/src/trace_processor/stats_table.cc
@@ -55,7 +55,9 @@
StatsTable::Cursor::Cursor(StatsTable* table)
: SqliteTable::Cursor(table), table_(table), storage_(table->storage_) {}
-int StatsTable::Cursor::Filter(const QueryConstraints&, sqlite3_value**) {
+int StatsTable::Cursor::Filter(const QueryConstraints&,
+ sqlite3_value**,
+ FilterHistory) {
*this = Cursor(table_);
return SQLITE_OK;
}
diff --git a/src/trace_processor/stats_table.h b/src/trace_processor/stats_table.h
index 3a1a591..3a25413 100644
--- a/src/trace_processor/stats_table.h
+++ b/src/trace_processor/stats_table.h
@@ -38,7 +38,9 @@
Cursor(StatsTable*);
// Implementation of SqliteTable::Cursor.
- int Filter(const QueryConstraints&, sqlite3_value**) override;
+ int Filter(const QueryConstraints&,
+ sqlite3_value**,
+ FilterHistory) override;
int Next() override;
int Eof() override;
int Column(sqlite3_context*, int N) override;
diff --git a/src/trace_processor/storage_table.cc b/src/trace_processor/storage_table.cc
index aec5810..09300d2 100644
--- a/src/trace_processor/storage_table.cc
+++ b/src/trace_processor/storage_table.cc
@@ -170,7 +170,8 @@
: SqliteTable::Cursor(table), table_(table) {}
int StorageTable::Cursor::Filter(const QueryConstraints& qc,
- sqlite3_value** argv) {
+ sqlite3_value** argv,
+ FilterHistory) {
iterator_ = table_->CreateBestRowIterator(qc, argv);
if (!iterator_)
return SQLITE_ERROR;
diff --git a/src/trace_processor/storage_table.h b/src/trace_processor/storage_table.h
index 74247f6..e03a776 100644
--- a/src/trace_processor/storage_table.h
+++ b/src/trace_processor/storage_table.h
@@ -37,7 +37,9 @@
Cursor(StorageTable* table);
// Implementation of SqliteTable::Cursor.
- int Filter(const QueryConstraints& qc, sqlite3_value** argv) override;
+ int Filter(const QueryConstraints& qc,
+ sqlite3_value** argv,
+ FilterHistory) override;
int Next() override;
int Eof() override;
int Column(sqlite3_context*, int N) override;
diff --git a/src/trace_processor/tables/macros_benchmark.cc b/src/trace_processor/tables/macros_benchmark.cc
index 779acb2..8150371 100644
--- a/src/trace_processor/tables/macros_benchmark.cc
+++ b/src/trace_processor/tables/macros_benchmark.cc
@@ -44,6 +44,32 @@
} // namespace trace_processor
} // namespace perfetto
+namespace {
+
+bool IsBenchmarkFunctionalOnly() {
+ return getenv("BENCHMARK_FUNCTIONAL_TEST_ONLY") != nullptr;
+}
+
+void TableFilterArgs(benchmark::internal::Benchmark* b) {
+ if (IsBenchmarkFunctionalOnly()) {
+ b->Arg(1024);
+ } else {
+ b->RangeMultiplier(8);
+ b->Range(1024, 2 * 1024 * 1024);
+ }
+}
+
+void TableSortArgs(benchmark::internal::Benchmark* b) {
+ if (IsBenchmarkFunctionalOnly()) {
+ b->Arg(64);
+ } else {
+ b->RangeMultiplier(8);
+ b->Range(1024, 256 * 1024);
+ }
+}
+
+} // namespace
+
using perfetto::trace_processor::ChildTestTable;
using perfetto::trace_processor::RootTestTable;
using perfetto::trace_processor::SqlValue;
@@ -80,9 +106,7 @@
it = child.IterateRows();
}
}
-BENCHMARK(BM_TableIteratorChild)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+BENCHMARK(BM_TableIteratorChild)->Apply(TableFilterArgs);
static void BM_TableFilterIdColumn(benchmark::State& state) {
StringPool pool;
@@ -96,9 +120,7 @@
benchmark::DoNotOptimize(root.Filter({root.id().eq(SqlValue::Long(30))}));
}
}
-BENCHMARK(BM_TableFilterIdColumn)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+BENCHMARK(BM_TableFilterIdColumn)->Apply(TableFilterArgs);
static void BM_TableFilterRootNonNullEqMatchMany(benchmark::State& state) {
StringPool pool;
@@ -118,9 +140,7 @@
root.Filter({root.root_non_null().eq(SqlValue::Long(0))}));
}
}
-BENCHMARK(BM_TableFilterRootNonNullEqMatchMany)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+BENCHMARK(BM_TableFilterRootNonNullEqMatchMany)->Apply(TableFilterArgs);
static void BM_TableFilterRootNullableEqMatchMany(benchmark::State& state) {
StringPool pool;
@@ -144,9 +164,7 @@
root.Filter({root.root_nullable().eq(SqlValue::Long(1))}));
}
}
-BENCHMARK(BM_TableFilterRootNullableEqMatchMany)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+BENCHMARK(BM_TableFilterRootNullableEqMatchMany)->Apply(TableFilterArgs);
static void BM_TableFilterChildNonNullEqMatchMany(benchmark::State& state) {
StringPool pool;
@@ -169,9 +187,7 @@
child.Filter({child.child_non_null().eq(SqlValue::Long(0))}));
}
}
-BENCHMARK(BM_TableFilterChildNonNullEqMatchMany)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+BENCHMARK(BM_TableFilterChildNonNullEqMatchMany)->Apply(TableFilterArgs);
static void BM_TableFilterChildNullableEqMatchMany(benchmark::State& state) {
StringPool pool;
@@ -197,9 +213,7 @@
child.Filter({child.child_nullable().eq(SqlValue::Long(1))}));
}
}
-BENCHMARK(BM_TableFilterChildNullableEqMatchMany)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+BENCHMARK(BM_TableFilterChildNullableEqMatchMany)->Apply(TableFilterArgs);
static void BM_TableFilterChildNonNullEqMatchManyInParent(
benchmark::State& state) {
@@ -224,8 +238,7 @@
}
}
BENCHMARK(BM_TableFilterChildNonNullEqMatchManyInParent)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+ ->Apply(TableFilterArgs);
static void BM_TableFilterChildNullableEqMatchManyInParent(
benchmark::State& state) {
@@ -250,8 +263,7 @@
}
}
BENCHMARK(BM_TableFilterChildNullableEqMatchManyInParent)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+ ->Apply(TableFilterArgs);
static void BM_TableFilterParentSortedEq(benchmark::State& state) {
StringPool pool;
@@ -270,9 +282,7 @@
root.Filter({root.root_sorted().eq(SqlValue::Long(22))}));
}
}
-BENCHMARK(BM_TableFilterParentSortedEq)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+BENCHMARK(BM_TableFilterParentSortedEq)->Apply(TableFilterArgs);
static void BM_TableFilterChildSortedEq(benchmark::State& state) {
StringPool pool;
@@ -293,9 +303,7 @@
child.Filter({child.child_sorted().eq(SqlValue::Long(22))}));
}
}
-BENCHMARK(BM_TableFilterChildSortedEq)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+BENCHMARK(BM_TableFilterChildSortedEq)->Apply(TableFilterArgs);
static void BM_TableFilterChildSortedEqInParent(benchmark::State& state) {
StringPool pool;
@@ -319,9 +327,7 @@
child.Filter({child.root_sorted().eq(SqlValue::Long(22))}));
}
}
-BENCHMARK(BM_TableFilterChildSortedEqInParent)
- ->RangeMultiplier(8)
- ->Range(1024, 2 * 1024 * 1024);
+BENCHMARK(BM_TableFilterChildSortedEqInParent)->Apply(TableFilterArgs);
static void BM_TableSortRootNonNull(benchmark::State& state) {
StringPool pool;
@@ -342,7 +348,7 @@
benchmark::DoNotOptimize(root.Sort({root.root_non_null().ascending()}));
}
}
-BENCHMARK(BM_TableSortRootNonNull)->RangeMultiplier(8)->Range(1024, 256 * 1024);
+BENCHMARK(BM_TableSortRootNonNull)->Apply(TableSortArgs);
static void BM_TableSortRootNullable(benchmark::State& state) {
StringPool pool;
@@ -365,9 +371,7 @@
benchmark::DoNotOptimize(root.Sort({root.root_nullable().ascending()}));
}
}
-BENCHMARK(BM_TableSortRootNullable)
- ->RangeMultiplier(8)
- ->Range(1024, 256 * 1024);
+BENCHMARK(BM_TableSortRootNullable)->Apply(TableSortArgs);
static void BM_TableSortChildNonNullInParent(benchmark::State& state) {
StringPool pool;
@@ -395,9 +399,7 @@
benchmark::DoNotOptimize(child.Sort({child.root_non_null().ascending()}));
}
}
-BENCHMARK(BM_TableSortChildNonNullInParent)
- ->RangeMultiplier(8)
- ->Range(1024, 256 * 1024);
+BENCHMARK(BM_TableSortChildNonNullInParent)->Apply(TableSortArgs);
static void BM_TableSortChildNullableInParent(benchmark::State& state) {
StringPool pool;
@@ -429,6 +431,4 @@
benchmark::DoNotOptimize(child.Sort({child.root_nullable().ascending()}));
}
}
-BENCHMARK(BM_TableSortChildNullableInParent)
- ->RangeMultiplier(8)
- ->Range(1024, 256 * 1024);
+BENCHMARK(BM_TableSortChildNullableInParent)->Apply(TableSortArgs);
diff --git a/src/trace_processor/tables/profiler_tables.h b/src/trace_processor/tables/profiler_tables.h
index 2561596..13f3330 100644
--- a/src/trace_processor/tables/profiler_tables.h
+++ b/src/trace_processor/tables/profiler_tables.h
@@ -42,18 +42,19 @@
PERFETTO_TP_TABLE(PERFETTO_TP_SYMBOL_DEF);
-#define PERFETTO_TP_HEAP_GRAPH_OBJECT_DEF(NAME, PARENT, C) \
- NAME(HeapGraphObjectTable, "heap_graph_object") \
- PERFETTO_TP_ROOT_TABLE(PARENT, C) \
- C(int64_t, upid) \
- C(int64_t, graph_sample_ts) \
- C(int64_t, object_id) \
- C(int64_t, self_size) \
- C(int64_t, retained_size) \
- C(int64_t, unique_retained_size) \
- C(int64_t, reference_set_id) \
- C(int32_t, reachable) \
- C(StringPool::Id, type_name) \
+#define PERFETTO_TP_HEAP_GRAPH_OBJECT_DEF(NAME, PARENT, C) \
+ NAME(HeapGraphObjectTable, "heap_graph_object") \
+ PERFETTO_TP_ROOT_TABLE(PARENT, C) \
+ C(int64_t, upid) \
+ C(int64_t, graph_sample_ts) \
+ C(int64_t, object_id) \
+ C(int64_t, self_size) \
+ C(int64_t, retained_size) \
+ C(int64_t, unique_retained_size) \
+ C(int64_t, reference_set_id) \
+ C(int32_t, reachable) \
+ C(StringPool::Id, type_name) \
+ C(base::Optional<StringPool::Id>, deobfuscated_type_name) \
C(base::Optional<StringPool::Id>, root_type)
PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_GRAPH_OBJECT_DEF);
@@ -64,7 +65,8 @@
C(int64_t, reference_set_id) \
C(int64_t, owner_id) \
C(int64_t, owned_id) \
- C(StringPool::Id, field_name)
+ C(StringPool::Id, field_name) \
+ C(base::Optional<StringPool::Id>, deobfuscated_field_name)
PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_GRAPH_REFERENCE_DEF);
diff --git a/src/trace_processor/thread_table.cc b/src/trace_processor/thread_table.cc
index c98127d..1ead7c5 100644
--- a/src/trace_processor/thread_table.cc
+++ b/src/trace_processor/thread_table.cc
@@ -73,7 +73,8 @@
: SqliteTable::Cursor(table), storage_(table->storage_), table_(table) {}
int ThreadTable::Cursor::Filter(const QueryConstraints& qc,
- sqlite3_value** argv) {
+ sqlite3_value** argv,
+ FilterHistory) {
*this = Cursor(table_);
min_ = 0;
diff --git a/src/trace_processor/thread_table.h b/src/trace_processor/thread_table.h
index 43484d1..152399f 100644
--- a/src/trace_processor/thread_table.h
+++ b/src/trace_processor/thread_table.h
@@ -43,7 +43,9 @@
Cursor(ThreadTable* table);
// Implementation of Table::Cursor.
- int Filter(const QueryConstraints&, sqlite3_value**) override;
+ int Filter(const QueryConstraints&,
+ sqlite3_value**,
+ FilterHistory) override;
int Next() override;
int Eof() override;
int Column(sqlite3_context*, int N) override;
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index 7243b42..2d40985 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -115,6 +115,7 @@
StringId name_id = 0;
uint32_t pid = 0;
base::Optional<UniquePid> parent_upid;
+ base::Optional<uint32_t> uid;
};
// Information about a unique thread seen in a trace.
diff --git a/src/trace_processor/vulkan_memory_tracker.cc b/src/trace_processor/vulkan_memory_tracker.cc
index 0ffebc1..310f73e 100644
--- a/src/trace_processor/vulkan_memory_tracker.cc
+++ b/src/trace_processor/vulkan_memory_tracker.cc
@@ -85,18 +85,37 @@
}
StringId VulkanMemoryTracker::FindMemoryTypeCounterString(
- uint32_t memory_type) {
+ uint32_t memory_type,
+ DeviceCounterType counter_type) {
StringId res = kNullStringId;
- auto it = memory_type_counter_string_map_.find(memory_type);
- if (it == memory_type_counter_string_map_.end()) {
- auto type_counter_str =
- vulkan_device_memory_counter_str_ + std::to_string(memory_type);
- res = context_->storage->InternString(
- base::StringView(type_counter_str.c_str(), type_counter_str.length()));
- memory_type_counter_string_map_.emplace(memory_type, res);
- return res;
+ std::unordered_map<uint32_t, StringId>::iterator it;
+ std::string type_counter_str;
+ switch (counter_type) {
+ case DeviceCounterType::kAllocationCounter:
+ it = memory_type_allocation_counter_string_map_.find(memory_type);
+ if (it == memory_type_allocation_counter_string_map_.end()) {
+ type_counter_str = vulkan_device_memory_counter_str_ +
+ std::to_string(memory_type) + ".allocation";
+ res = context_->storage->InternString(base::StringView(
+ type_counter_str.c_str(), type_counter_str.length()));
+ memory_type_allocation_counter_string_map_.emplace(memory_type, res);
+ } else {
+ res = it->second;
+ }
+ break;
+ case DeviceCounterType::kBindCounter:
+ it = memory_type_bind_counter_string_map_.find(memory_type);
+ if (it == memory_type_bind_counter_string_map_.end()) {
+ type_counter_str = vulkan_device_memory_counter_str_ +
+ std::to_string(memory_type) + ".bind";
+ res = context_->storage->InternString(base::StringView(
+ type_counter_str.c_str(), type_counter_str.length()));
+ memory_type_bind_counter_string_map_.emplace(memory_type, res);
+ } else {
+ res = it->second;
+ }
+ break;
}
- res = it->second;
return res;
}
diff --git a/src/trace_processor/vulkan_memory_tracker.h b/src/trace_processor/vulkan_memory_tracker.h
index a501f4a..f7cc9b8 100644
--- a/src/trace_processor/vulkan_memory_tracker.h
+++ b/src/trace_processor/vulkan_memory_tracker.h
@@ -31,6 +31,11 @@
class VulkanMemoryTracker {
public:
+ enum class DeviceCounterType {
+ kAllocationCounter = 0,
+ kBindCounter = 1,
+ };
+
explicit VulkanMemoryTracker(TraceProcessorContext* context);
~VulkanMemoryTracker() = default;
@@ -52,7 +57,8 @@
StringId FindOperationString(VulkanMemoryEvent::Operation);
StringId FindAllocationScopeString(VulkanMemoryEvent::AllocationScope);
StringId FindAllocationScopeCounterString(VulkanMemoryEvent::AllocationScope);
- StringId FindMemoryTypeCounterString(uint32_t /*memory_type*/);
+ StringId FindMemoryTypeCounterString(uint32_t /*memory_type*/,
+ DeviceCounterType);
private:
TraceProcessorContext* const context_;
@@ -64,7 +70,9 @@
std::vector<StringId> scope_strs_id_;
std::vector<StringId> scope_counter_strs_id_;
std::unordered_map<uint32_t /*memory_type*/, StringId>
- memory_type_counter_string_map_;
+ memory_type_allocation_counter_string_map_;
+ std::unordered_map<uint32_t /*memory_type*/, StringId>
+ memory_type_bind_counter_string_map_;
void SetupSourceAndTypeInternedStrings();
};
diff --git a/src/trace_processor/window_operator_table.cc b/src/trace_processor/window_operator_table.cc
index a7a49e5..1d801f8 100644
--- a/src/trace_processor/window_operator_table.cc
+++ b/src/trace_processor/window_operator_table.cc
@@ -103,7 +103,8 @@
: SqliteTable::Cursor(table), table_(table) {}
int WindowOperatorTable::Cursor::Filter(const QueryConstraints& qc,
- sqlite3_value** argv) {
+ sqlite3_value** argv,
+ FilterHistory) {
*this = Cursor(table_);
window_start_ = table_->window_start_;
window_end_ = table_->window_start_ + table_->window_dur_;
diff --git a/src/trace_processor/window_operator_table.h b/src/trace_processor/window_operator_table.h
index 41fbbb7..504ec13 100644
--- a/src/trace_processor/window_operator_table.h
+++ b/src/trace_processor/window_operator_table.h
@@ -43,7 +43,9 @@
Cursor(WindowOperatorTable*);
// Implementation of SqliteTable::Cursor.
- int Filter(const QueryConstraints& qc, sqlite3_value**) override;
+ int Filter(const QueryConstraints& qc,
+ sqlite3_value**,
+ FilterHistory) override;
int Next() override;
int Eof() override;
int Column(sqlite3_context*, int N) override;
diff --git a/src/traced/probes/ps/process_stats_data_source.cc b/src/traced/probes/ps/process_stats_data_source.cc
index 6c9d2da..de68e0d 100644
--- a/src/traced/probes/ps/process_stats_data_source.cc
+++ b/src/traced/probes/ps/process_stats_data_source.cc
@@ -171,9 +171,14 @@
}
void ProcessStatsDataSource::OnPids(const std::vector<int32_t>& pids) {
- PERFETTO_METATRACE_SCOPED(TAG_PROC_POLLERS, PS_ON_PIDS);
if (!enable_on_demand_dumps_)
return;
+ WriteProcessTree(pids);
+}
+
+void ProcessStatsDataSource::WriteProcessTree(
+ const std::vector<int32_t>& pids) {
+ PERFETTO_METATRACE_SCOPED(TAG_PROC_POLLERS, PS_ON_PIDS);
PERFETTO_DCHECK(!cur_ps_tree_);
int pids_scanned = 0;
for (int32_t pid : pids) {
@@ -414,7 +419,7 @@
// Ensure that we write once long-term process info (e.g., name) for new pids
// that we haven't seen before.
- OnPids(pids);
+ WriteProcessTree(pids);
}
// Returns true if the stats for the given |pid| have been written, false it
diff --git a/src/traced/probes/ps/process_stats_data_source.h b/src/traced/probes/ps/process_stats_data_source.h
index b2fa51c..f301e5d 100644
--- a/src/traced/probes/ps/process_stats_data_source.h
+++ b/src/traced/probes/ps/process_stats_data_source.h
@@ -105,6 +105,9 @@
void WriteAllProcessStats();
bool WriteMemCounters(int32_t pid, const std::string& proc_status);
+ // Scans /proc/pid/status and writes the ProcessTree packet for input pids.
+ void WriteProcessTree(const std::vector<int32_t>& pids);
+
// Read and "latch" the current procfs scan-start timestamp, which
// we reset only in FinalizeCurPacket.
uint64_t CacheProcFsScanStartTimestamp();
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index 844da88..7a8ef42 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -22,9 +22,6 @@
public_deps = [
":common",
"../../include/perfetto/ext/tracing/core",
- "../../protos/perfetto/common:lite",
- "../../protos/perfetto/trace:minimal_lite",
- "../../protos/perfetto/trace:trusted_lite",
"../../protos/perfetto/trace:zero",
"../../protos/perfetto/trace/interned_data:zero",
"../../protos/perfetto/trace/track_event:zero",
@@ -32,7 +29,8 @@
deps = [
"../../gn:default_deps",
"../../include/perfetto/tracing",
- "../../protos/perfetto/config:lite",
+ "../../protos/perfetto/common:zero",
+ "../../protos/perfetto/config:zero",
"../../protos/perfetto/trace/perfetto:zero", # For MetatraceWriter.
"../base",
"../protozero",
@@ -61,6 +59,7 @@
"core/tracing_service_impl.h",
"core/virtual_destructors.cc",
]
+ assert_no_deps = [ "//gn:protobuf_lite" ]
}
# TODO(primiano): Remove this target as soon as chromium's
@@ -252,7 +251,7 @@
deps = [
":common",
"../../include/perfetto/tracing/core",
- "../../protos/perfetto/config:lite",
+ "../../protos/perfetto/config:cpp",
"../base",
"../tracing",
]
diff --git a/src/tracing/core/trace_packet_unittest.cc b/src/tracing/core/trace_packet_unittest.cc
index 0469ae8..c8fb8f9 100644
--- a/src/tracing/core/trace_packet_unittest.cc
+++ b/src/tracing/core/trace_packet_unittest.cc
@@ -20,36 +20,11 @@
#include "protos/perfetto/trace/trace.pb.h"
#include "protos/perfetto/trace/trace_packet.pb.h"
-#include "protos/perfetto/trace/trusted_packet.pb.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
namespace {
-static_assert(static_cast<int>(TracePacket::kPacketFieldNumber) ==
- static_cast<int>(protos::Trace::kPacketFieldNumber),
- "packet field id mismatch");
-
-static_assert(
- static_cast<int>(protos::TracePacket::kTrustedUidFieldNumber) ==
- static_cast<int>(protos::TrustedPacket::kTrustedUidFieldNumber),
- "trusted_uid field id mismatch");
-
-static_assert(
- static_cast<int>(protos::TracePacket::kTraceConfigFieldNumber) ==
- static_cast<int>(protos::TrustedPacket::kTraceConfigFieldNumber),
- "trace_config field id mismatch");
-
-static_assert(
- static_cast<int>(protos::TracePacket::kTraceStatsFieldNumber) ==
- static_cast<int>(protos::TrustedPacket::kTraceStatsFieldNumber),
- "trace_stats field id mismatch");
-
-static_assert(
- static_cast<int>(protos::TracePacket::kClockSnapshotFieldNumber) ==
- static_cast<int>(protos::TrustedPacket::kClockSnapshotFieldNumber),
- "clock_snapshot field id mismatch");
-
TEST(TracePacketTest, Simple) {
protos::TracePacket proto;
proto.mutable_for_testing()->set_str("string field");
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index 26331d7..0e3b424 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -49,15 +49,20 @@
#include "perfetto/ext/tracing/core/shared_memory_abi.h"
#include "perfetto/ext/tracing/core/trace_packet.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/protozero/static_buffer.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "perfetto/tracing/core/tracing_service_state.h"
#include "src/tracing/core/packet_stream_validator.h"
#include "src/tracing/core/shared_memory_arbiter_impl.h"
#include "src/tracing/core/trace_buffer.h"
-#include "protos/perfetto/trace/clock_snapshot.pb.h"
-#include "protos/perfetto/trace/system_info.pb.h"
-#include "protos/perfetto/trace/trusted_packet.pb.h"
+#include "protos/perfetto/common/trace_stats.pbzero.h"
+#include "protos/perfetto/config/trace_config.pbzero.h"
+#include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+#include "protos/perfetto/trace/system_info.pbzero.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "protos/perfetto/trace/trigger.pbzero.h"
// General note: this class must assume that Producers are malicious and will
// try to crash / exploit this class. We can trust pointers because they come
@@ -132,6 +137,14 @@
return static_cast<int32_t>(acc);
}
+void SerializeAndAppendPacket(std::vector<TracePacket>* packets,
+ std::vector<uint8_t> packet) {
+ Slice slice = Slice::Allocate(packet.size());
+ memcpy(slice.own_data(), packet.data(), packet.size());
+ packets->emplace_back();
+ packets->back().AddSlice(std::move(slice));
+}
+
} // namespace
// These constants instead are defined in the header because are used by tests.
@@ -1540,21 +1553,18 @@
// truncated packets are also rejected, so the producer can't give us a
// partial packet (e.g., a truncated string) which only becomes valid when
// the trusted data is appended here.
- protos::TrustedPacket trusted_packet;
- trusted_packet.set_trusted_uid(
+ Slice slice = Slice::Allocate(32);
+ protozero::StaticBuffered<protos::pbzero::TracePacket> trusted_packet(
+ slice.own_data(), slice.size);
+ trusted_packet->set_trusted_uid(
static_cast<int32_t>(sequence_properties.producer_uid_trusted));
- trusted_packet.set_trusted_packet_sequence_id(
+ trusted_packet->set_trusted_packet_sequence_id(
tracing_session->GetPacketSequenceID(
sequence_properties.producer_id_trusted,
sequence_properties.writer_id));
if (previous_packet_dropped)
- trusted_packet.set_previous_packet_dropped(previous_packet_dropped);
- static constexpr size_t kTrustedBufSize = 16;
- Slice slice = Slice::Allocate(kTrustedBufSize);
- PERFETTO_CHECK(
- trusted_packet.SerializeToArray(slice.own_data(), kTrustedBufSize));
- slice.size = static_cast<size_t>(trusted_packet.GetCachedSize());
- PERFETTO_DCHECK(slice.size > 0 && slice.size <= kTrustedBufSize);
+ trusted_packet->set_previous_packet_dropped(previous_packet_dropped);
+ slice.size = trusted_packet.Finalize();
packet.AddSlice(std::move(slice));
// Append the packet (inclusive of the trusted uid) to |packets|.
@@ -2160,23 +2170,17 @@
// The sync marks are used to tokenize large traces efficiently.
// See description in trace_packet.proto.
if (sync_marker_packet_size_ == 0) {
- // Serialize the marker and the uid separately to guarantee that the marker
- // is serialzied at the end and is adjacent to the start of the next packet.
- int size_left = static_cast<int>(sizeof(sync_marker_packet_));
- uint8_t* dst = &sync_marker_packet_[0];
- protos::TrustedPacket packet;
- packet.set_trusted_uid(static_cast<int32_t>(uid_));
- packet.set_trusted_packet_sequence_id(kServicePacketSequenceID);
- PERFETTO_CHECK(packet.SerializeToArray(dst, size_left));
- size_left -= packet.ByteSize();
- sync_marker_packet_size_ += static_cast<size_t>(packet.ByteSize());
- dst += sync_marker_packet_size_;
+ // The marker ABI expects that the marker is written after the uid.
+ // Protozero guarantees that fields are written in the same order of the
+ // calls. The ResynchronizeTraceStreamUsingSyncMarker test verifies the ABI.
+ protozero::StaticBuffered<protos::pbzero::TracePacket> packet(
+ &sync_marker_packet_[0], sizeof(sync_marker_packet_));
+ packet->set_trusted_uid(static_cast<int32_t>(uid_));
+ packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
- packet.Clear();
- packet.set_synchronization_marker(kSyncMarker, sizeof(kSyncMarker));
- PERFETTO_CHECK(packet.SerializeToArray(dst, size_left));
- sync_marker_packet_size_ += static_cast<size_t>(packet.ByteSize());
- PERFETTO_CHECK(sync_marker_packet_size_ <= sizeof(sync_marker_packet_));
+ // Keep this last.
+ packet->set_synchronization_marker(kSyncMarker, sizeof(kSyncMarker));
+ sync_marker_packet_size_ = packet.Finalize();
}
packets->emplace_back();
packets->back().AddSlice(&sync_marker_packet_[0], sync_marker_packet_size_);
@@ -2184,33 +2188,36 @@
void TracingServiceImpl::SnapshotClocks(std::vector<TracePacket>* packets,
bool set_root_timestamp) {
- protos::TrustedPacket packet;
- protos::ClockSnapshot* clock_snapshot = packet.mutable_clock_snapshot();
+ protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+ uint64_t root_timestamp_ns = 0;
+ auto* clock_snapshot = packet->set_clock_snapshot();
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX) && \
!PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
struct {
clockid_t id;
- protos::ClockSnapshot::Clock::BuiltinClocks type;
+ protos::pbzero::ClockSnapshot::Clock::BuiltinClocks type;
struct timespec ts;
} clocks[] = {
- {CLOCK_BOOTTIME, protos::ClockSnapshot::Clock::BOOTTIME, {0, 0}},
+ {CLOCK_BOOTTIME, protos::pbzero::ClockSnapshot::Clock::BOOTTIME, {0, 0}},
{CLOCK_REALTIME_COARSE,
- protos::ClockSnapshot::Clock::REALTIME_COARSE,
+ protos::pbzero::ClockSnapshot::Clock::REALTIME_COARSE,
{0, 0}},
{CLOCK_MONOTONIC_COARSE,
- protos::ClockSnapshot::Clock::MONOTONIC_COARSE,
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC_COARSE,
{0, 0}},
- {CLOCK_REALTIME, protos::ClockSnapshot::Clock::REALTIME, {0, 0}},
- {CLOCK_MONOTONIC, protos::ClockSnapshot::Clock::MONOTONIC, {0, 0}},
+ {CLOCK_REALTIME, protos::pbzero::ClockSnapshot::Clock::REALTIME, {0, 0}},
+ {CLOCK_MONOTONIC,
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC,
+ {0, 0}},
{CLOCK_MONOTONIC_RAW,
- protos::ClockSnapshot::Clock::MONOTONIC_RAW,
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC_RAW,
{0, 0}},
{CLOCK_PROCESS_CPUTIME_ID,
- protos::ClockSnapshot::Clock::PROCESS_CPUTIME,
+ protos::pbzero::ClockSnapshot::Clock::PROCESS_CPUTIME,
{0, 0}},
{CLOCK_THREAD_CPUTIME_ID,
- protos::ClockSnapshot::Clock::THREAD_CPUTIME,
+ protos::pbzero::ClockSnapshot::Clock::THREAD_CPUTIME,
{0, 0}},
};
// First snapshot all the clocks as atomically as we can.
@@ -2220,11 +2227,11 @@
}
for (auto& clock : clocks) {
if (set_root_timestamp &&
- clock.type == protos::ClockSnapshot::Clock::BOOTTIME) {
- packet.set_timestamp(
- static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count()));
+ clock.type == protos::pbzero::ClockSnapshot::Clock::BOOTTIME) {
+ root_timestamp_ns =
+ static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count());
}
- protos::ClockSnapshot::Clock* c = clock_snapshot->add_clocks();
+ auto* c = clock_snapshot->add_clocks();
c->set_clock_id(static_cast<uint32_t>(clock.type));
c->set_timestamp(
static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count()));
@@ -2232,32 +2239,27 @@
#else // !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
auto wall_time_ns = static_cast<uint64_t>(base::GetWallTimeNs().count());
if (set_root_timestamp)
- packet.set_timestamp(wall_time_ns);
- protos::ClockSnapshot::Clock* c = clock_snapshot->add_clocks();
- c->set_clock_id(protos::ClockSnapshot::Clock::MONOTONIC);
+ root_timestamp_ns = wall_time_ns;
+ auto* c = clock_snapshot->add_clocks();
+ c->set_clock_id(protos::pbzero::ClockSnapshot::Clock::MONOTONIC);
c->set_timestamp(wall_time_ns);
#endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
- packet.set_trusted_uid(static_cast<int32_t>(uid_));
- packet.set_trusted_packet_sequence_id(kServicePacketSequenceID);
- Slice slice = Slice::Allocate(static_cast<size_t>(packet.ByteSize()));
- PERFETTO_CHECK(packet.SerializeWithCachedSizesToArray(slice.own_data()));
- packets->emplace_back();
- packets->back().AddSlice(std::move(slice));
+ if (root_timestamp_ns)
+ packet->set_timestamp(root_timestamp_ns);
+ packet->set_trusted_uid(static_cast<int32_t>(uid_));
+ packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+
+ SerializeAndAppendPacket(packets, packet.SerializeAsArray());
}
void TracingServiceImpl::SnapshotStats(TracingSession* tracing_session,
std::vector<TracePacket>* packets) {
- protos::TrustedPacket packet;
- packet.set_trusted_uid(static_cast<int32_t>(uid_));
- packet.set_trusted_packet_sequence_id(kServicePacketSequenceID);
-
- protos::TraceStats* trace_stats = packet.mutable_trace_stats();
- GetTraceStats(tracing_session).ToProto(trace_stats);
- Slice slice = Slice::Allocate(static_cast<size_t>(packet.ByteSize()));
- PERFETTO_CHECK(packet.SerializeWithCachedSizesToArray(slice.own_data()));
- packets->emplace_back();
- packets->back().AddSlice(std::move(slice));
+ protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+ packet->set_trusted_uid(static_cast<int32_t>(uid_));
+ packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+ GetTraceStats(tracing_session).Serialize(packet->set_trace_stats());
+ SerializeAndAppendPacket(packets, packet.SerializeAsArray());
}
TraceStats TracingServiceImpl::GetTraceStats(TracingSession* tracing_session) {
@@ -2291,14 +2293,11 @@
if (tracing_session->did_emit_config)
return;
tracing_session->did_emit_config = true;
- protos::TrustedPacket packet;
- tracing_session->config.ToProto(packet.mutable_trace_config());
- packet.set_trusted_uid(static_cast<int32_t>(uid_));
- packet.set_trusted_packet_sequence_id(kServicePacketSequenceID);
- Slice slice = Slice::Allocate(static_cast<size_t>(packet.ByteSize()));
- PERFETTO_CHECK(packet.SerializeWithCachedSizesToArray(slice.own_data()));
- packets->emplace_back();
- packets->back().AddSlice(std::move(slice));
+ protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+ packet->set_trusted_uid(static_cast<int32_t>(uid_));
+ packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+ tracing_session->config.Serialize(packet->set_trace_config());
+ SerializeAndAppendPacket(packets, packet.SerializeAsArray());
}
void TracingServiceImpl::MaybeEmitSystemInfo(
@@ -2307,24 +2306,21 @@
if (tracing_session->did_emit_system_info)
return;
tracing_session->did_emit_system_info = true;
- protos::TrustedPacket packet;
+ protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
- protos::SystemInfo* info = packet.mutable_system_info();
+ auto* info = packet->set_system_info();
struct utsname uname_info;
if (uname(&uname_info) == 0) {
- protos::Utsname* utsname_info = info->mutable_utsname();
+ auto* utsname_info = info->set_utsname();
utsname_info->set_sysname(uname_info.sysname);
utsname_info->set_version(uname_info.version);
utsname_info->set_machine(uname_info.machine);
utsname_info->set_release(uname_info.release);
}
#endif
- packet.set_trusted_uid(static_cast<int32_t>(uid_));
- packet.set_trusted_packet_sequence_id(kServicePacketSequenceID);
- Slice slice = Slice::Allocate(static_cast<size_t>(packet.ByteSize()));
- PERFETTO_CHECK(packet.SerializeWithCachedSizesToArray(slice.own_data()));
- packets->emplace_back();
- packets->back().AddSlice(std::move(slice));
+ packet->set_trusted_uid(static_cast<int32_t>(uid_));
+ packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+ SerializeAndAppendPacket(packets, packet.SerializeAsArray());
}
void TracingServiceImpl::MaybeEmitReceivedTriggers(
@@ -2335,20 +2331,16 @@
for (size_t i = tracing_session->num_triggers_emitted_into_trace;
i < tracing_session->received_triggers.size(); ++i) {
const auto& info = tracing_session->received_triggers[i];
- protos::TrustedPacket packet;
-
- protos::Trigger* trigger = packet.mutable_trigger();
+ protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+ auto* trigger = packet->set_trigger();
trigger->set_trigger_name(info.trigger_name);
trigger->set_producer_name(info.producer_name);
trigger->set_trusted_producer_uid(static_cast<int32_t>(info.producer_uid));
- packet.set_timestamp(info.boot_time_ns);
- packet.set_trusted_uid(static_cast<int32_t>(uid_));
- packet.set_trusted_packet_sequence_id(kServicePacketSequenceID);
- Slice slice = Slice::Allocate(static_cast<size_t>(packet.ByteSize()));
- PERFETTO_CHECK(packet.SerializeWithCachedSizesToArray(slice.own_data()));
- packets->emplace_back();
- packets->back().AddSlice(std::move(slice));
+ packet->set_timestamp(info.boot_time_ns);
+ packet->set_trusted_uid(static_cast<int32_t>(uid_));
+ packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+ SerializeAndAppendPacket(packets, packet.SerializeAsArray());
++tracing_session->num_triggers_emitted_into_trace;
}
}
diff --git a/src/tracing/internal/tracing_muxer_impl.cc b/src/tracing/internal/tracing_muxer_impl.cc
index 1ce6f93..a185f25 100644
--- a/src/tracing/internal/tracing_muxer_impl.cc
+++ b/src/tracing/internal/tracing_muxer_impl.cc
@@ -37,7 +37,6 @@
#include "perfetto/tracing/trace_writer_base.h"
#include "perfetto/tracing/tracing.h"
#include "perfetto/tracing/tracing_backend.h"
-#include "protos/perfetto/config/trace_config.pb.h"
#include "src/tracing/internal/in_process_tracing_backend.h"
#include "src/tracing/internal/system_tracing_backend.h"
@@ -59,12 +58,8 @@
uint64_t ComputeConfigHash(const DataSourceConfig& config) {
base::Hash hasher;
- perfetto::protos::DataSourceConfig config_proto;
- config.ToProto(&config_proto);
- std::string config_bytes;
- bool serialized = config_proto.SerializeToString(&config_bytes);
- PERFETTO_DCHECK(serialized);
- hasher.Update(&config_bytes[0], config_bytes.size());
+ std::string config_bytes = config.SerializeAsString();
+ hasher.Update(config_bytes.data(), config_bytes.size());
return hasher.digest();
}
diff --git a/test/metrics/android_process_growth.out b/test/metrics/android_process_growth.out
deleted file mode 100644
index e108056..0000000
--- a/test/metrics/android_process_growth.out
+++ /dev/null
@@ -1,14 +0,0 @@
-android_process_growth {
- instance_metrics {
- pid: 3
- process_name: "com.google.android.calendar"
- anon_and_swap_start_value: 2000
- anon_and_swap_change_bytes: 4000
- }
- instance_metrics {
- pid: 4
- process_name: "com.google.android.calendar"
- anon_and_swap_start_value: 150
- anon_and_swap_change_bytes: 0
- }
-}
diff --git a/test/metrics/android_process_growth.py b/test/metrics/android_process_growth.py
deleted file mode 100644
index 75bdece..0000000
--- a/test/metrics/android_process_growth.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2018 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.
-
-from os import sys, path
-
-sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
-import synth_common
-
-anon_member = 1
-swap_member = 2
-
-trace = synth_common.create_trace()
-trace.add_process_tree_packet()
-trace.add_process(1, 0, 'init')
-trace.add_process(2, 1, 'system_server')
-trace.add_process(3, 1, 'com.google.android.calendar')
-trace.add_process(4, 1, 'com.google.android.calendar')
-
-trace.add_ftrace_packet(cpu=0)
-trace.add_rss_stat(100, 3, anon_member, 1000)
-trace.add_rss_stat(100, 3, swap_member, 1000)
-trace.add_rss_stat(100, 4, anon_member, 100)
-trace.add_rss_stat(100, 4, swap_member, 50)
-
-trace.add_rss_stat(200, 3, anon_member, 2000)
-trace.add_rss_stat(200, 3, swap_member, 2000)
-trace.add_rss_stat(200, 4, anon_member, 1000)
-trace.add_rss_stat(200, 4, swap_member, 100)
-
-trace.add_rss_stat(300, 3, anon_member, 3000)
-trace.add_rss_stat(300, 3, swap_member, 3000)
-trace.add_rss_stat(300, 4, anon_member, 50)
-trace.add_rss_stat(300, 4, swap_member, 100)
-
-print(trace.trace.SerializeToString())
diff --git a/test/metrics/heap_profile.textproto b/test/metrics/heap_profile.textproto
index 831b002..d7dcfd7 100644
--- a/test/metrics/heap_profile.textproto
+++ b/test/metrics/heap_profile.textproto
@@ -4,11 +4,13 @@
pid: 1
ppid: 0
cmdline: "init"
+ uid: 0
}
processes {
pid: 2
ppid: 1
cmdline: "system_server"
+ uid: 1000
}
}
}
diff --git a/test/metrics/heap_profile_callsites.out b/test/metrics/heap_profile_callsites.out
index 5f8c14c..6079714 100644
--- a/test/metrics/heap_profile_callsites.out
+++ b/test/metrics/heap_profile_callsites.out
@@ -2,6 +2,10 @@
instance_stats {
pid: 2
process_name: "system_server"
+ process {
+ name: "system_server"
+ uid: 1000
+ }
callsites {
hash: -2067767828047084124
parent_hash: 3061552492032359760
diff --git a/test/metrics/index b/test/metrics/index
index 8f29693..0ee6a7f 100644
--- a/test/metrics/index
+++ b/test/metrics/index
@@ -4,7 +4,6 @@
# Synthetic traces
android_mem_by_priority.py android_mem android_mem_by_priority.out
-android_process_growth.py android_process_growth android_process_growth.out
android_lmk.py android_lmk android_mem_lmk.out
android_ion.py android_ion android_ion.out
diff --git a/test/metrics/java_heap_stats.out b/test/metrics/java_heap_stats.out
index 64db708..f818457 100644
--- a/test/metrics/java_heap_stats.out
+++ b/test/metrics/java_heap_stats.out
@@ -1,7 +1,10 @@
java_heap_stats {
instance_stats {
upid: 2
- process_name: "system_server"
+ process {
+ name: "system_server"
+ uid: 1000
+ }
samples {
ts: 10
heap_size: 224
diff --git a/test/synth_common.py b/test/synth_common.py
index 3383b81..142e76e 100644
--- a/test/synth_common.py
+++ b/test/synth_common.py
@@ -173,11 +173,13 @@
if ts is not None:
self.packet.timestamp = ts
- def add_process(self, pid, ppid, cmdline):
+ def add_process(self, pid, ppid, cmdline, uid=None):
process = self.packet.process_tree.processes.add()
process.pid = pid
process.ppid = ppid
process.cmdline.append(cmdline)
+ if uid is not None:
+ process.uid = uid
self.proc_map[pid] = cmdline
def add_thread(self, tid, tgid, cmdline):
diff --git a/test/trace_processor/counters_ref_type_null.sql b/test/trace_processor/counters_ref_type_null.sql
index 557b933..36a0b90 100644
--- a/test/trace_processor/counters_ref_type_null.sql
+++ b/test/trace_processor/counters_ref_type_null.sql
@@ -1,3 +1,3 @@
-select id, counter_id, ts, value, arg_set_id, name, ref, ref_type from counters
+select ts, value, name, ref, ref_type from counters
where name = 'MemAvailable' and ref_type is null
limit 10
diff --git a/test/trace_processor/counters_ref_type_null_memory_counters.out b/test/trace_processor/counters_ref_type_null_memory_counters.out
index 0457994..d416b76 100644
--- a/test/trace_processor/counters_ref_type_null_memory_counters.out
+++ b/test/trace_processor/counters_ref_type_null_memory_counters.out
@@ -1,11 +1,11 @@
-"id","counter_id","ts","value","arg_set_id","name","ref","ref_type"
-4294968280,984,22240334823167,2696392704.000000,0,"MemAvailable",0,"[NULL]"
-4294969268,984,22240356169836,2696392704.000000,0,"MemAvailable",0,"[NULL]"
-4294970256,984,22240468594483,2696392704.000000,0,"MemAvailable",0,"[NULL]"
-4294971244,984,22240566948190,2696392704.000000,0,"MemAvailable",0,"[NULL]"
-4294972232,984,22240667383304,2696392704.000000,0,"MemAvailable",0,"[NULL]"
-4294973220,984,22240766505085,2696392704.000000,0,"MemAvailable",0,"[NULL]"
-4294974208,984,22240866794106,2696392704.000000,0,"MemAvailable",0,"[NULL]"
-4294975196,984,22240968271928,2696392704.000000,0,"MemAvailable",0,"[NULL]"
-4294976184,984,22241065777407,2696392704.000000,0,"MemAvailable",0,"[NULL]"
-4294977172,984,22241165839708,2696392704.000000,0,"MemAvailable",0,"[NULL]"
+"ts","value","name","ref","ref_type"
+22240334823167,2696392704.000000,"MemAvailable",0,"[NULL]"
+22240356169836,2696392704.000000,"MemAvailable",0,"[NULL]"
+22240468594483,2696392704.000000,"MemAvailable",0,"[NULL]"
+22240566948190,2696392704.000000,"MemAvailable",0,"[NULL]"
+22240667383304,2696392704.000000,"MemAvailable",0,"[NULL]"
+22240766505085,2696392704.000000,"MemAvailable",0,"[NULL]"
+22240866794106,2696392704.000000,"MemAvailable",0,"[NULL]"
+22240968271928,2696392704.000000,"MemAvailable",0,"[NULL]"
+22241065777407,2696392704.000000,"MemAvailable",0,"[NULL]"
+22241165839708,2696392704.000000,"MemAvailable",0,"[NULL]"
diff --git a/test/trace_processor/heap_graph.textproto b/test/trace_processor/heap_graph.textproto
index b785578..4001fcf 100644
--- a/test/trace_processor/heap_graph.textproto
+++ b/test/trace_processor/heap_graph.textproto
@@ -4,11 +4,13 @@
pid: 1
ppid: 0
cmdline: "init"
+ uid: 0
}
processes {
pid: 2
ppid: 1
cmdline: "system_server"
+ uid: 1000
}
}
}
diff --git a/test/trace_processor/heap_graph_object.out b/test/trace_processor/heap_graph_object.out
index b0f9e43..b3cad4a 100644
--- a/test/trace_processor/heap_graph_object.out
+++ b/test/trace_processor/heap_graph_object.out
@@ -1,4 +1,4 @@
-"id","type","upid","graph_sample_ts","object_id","self_size","retained_size","unique_retained_size","reference_set_id","reachable","type_name","root_type"
-0,"heap_graph_object",2,10,1,64,96,96,0,1,"FactoryProducerDelegateImplActor","ROOT_JAVA_FRAME"
-1,"heap_graph_object",2,10,2,32,32,32,1,1,"Foo","[NULL]"
-2,"heap_graph_object",2,10,3,128,-1,0,1,0,"Foo","[NULL]"
+"id","type","upid","graph_sample_ts","object_id","self_size","retained_size","unique_retained_size","reference_set_id","reachable","type_name","deobfuscated_type_name","root_type"
+0,"heap_graph_object",2,10,1,64,96,96,0,1,"FactoryProducerDelegateImplActor","[NULL]","ROOT_JAVA_FRAME"
+1,"heap_graph_object",2,10,2,32,32,32,1,1,"Foo","[NULL]","[NULL]"
+2,"heap_graph_object",2,10,3,128,-1,-1,1,0,"Foo","[NULL]","[NULL]"
diff --git a/test/trace_processor/heap_graph_reference.out b/test/trace_processor/heap_graph_reference.out
index 3be9676..7cdaad2 100644
--- a/test/trace_processor/heap_graph_reference.out
+++ b/test/trace_processor/heap_graph_reference.out
@@ -1,2 +1,2 @@
-"id","type","reference_set_id","owner_id","owned_id","field_name"
-0,"heap_graph_reference",0,0,1,"FactoryProducerDelegateImplActor.foo"
+"id","type","reference_set_id","owner_id","owned_id","field_name","deobfuscated_field_name"
+0,"heap_graph_reference",0,0,1,"FactoryProducerDelegateImplActor.foo","[NULL]"
diff --git a/test/trace_processor/index b/test/trace_processor/index
index 958b11e..808b2cf 100644
--- a/test/trace_processor/index
+++ b/test/trace_processor/index
@@ -12,6 +12,7 @@
# Test for the process<>thread tracking logic.
synth_process_tracking.py process_tracking.sql process_tracking.out
+synth_process_tracking.py process_tracking_uid.sql process_tracking_uid.out
process_tracking_short_lived_1.py process_tracking.sql process_tracking_process_tracking_short_lived_1.out
process_tracking_short_lived_2.py process_tracking.sql process_tracking_process_tracking_short_lived_2.out
process_tracking_exec.py process_tracking.sql process_tracking_process_tracking_exec.out
diff --git a/test/trace_processor/mm_event.out b/test/trace_processor/mm_event.out
index a26a895c2..aee7eb1 100644
--- a/test/trace_processor/mm_event.out
+++ b/test/trace_processor/mm_event.out
@@ -1,41 +1,41 @@
-"id","ts","name","value","ref","ref_type","arg_set_id"
-4294967296,1409847208580693,"mem.mm.min_flt.count",1.000000,0,"upid",0
-4294967297,1409847208580693,"mem.mm.min_flt.max_lat",9.000000,0,"upid",0
-4294967298,1409847208580693,"mem.mm.min_flt.avg_lat",9.000000,0,"upid",0
-4294967299,1409847209537724,"mem.mm.min_flt.count",1.000000,0,"upid",0
-4294967300,1409847209537724,"mem.mm.min_flt.max_lat",759.000000,0,"upid",0
-4294967301,1409847209537724,"mem.mm.min_flt.avg_lat",759.000000,0,"upid",0
-4294967302,1409847213761006,"mem.mm.min_flt.count",1.000000,0,"upid",0
-4294967303,1409847213761006,"mem.mm.min_flt.max_lat",10.000000,0,"upid",0
-4294967304,1409847213761006,"mem.mm.min_flt.avg_lat",10.000000,0,"upid",0
-4294967305,1409847214052256,"mem.mm.min_flt.count",1.000000,0,"upid",0
-4294967306,1409847214052256,"mem.mm.min_flt.max_lat",90.000000,0,"upid",0
-4294967307,1409847214052256,"mem.mm.min_flt.avg_lat",90.000000,0,"upid",0
-4294967308,1409847216341006,"mem.mm.min_flt.count",1.000000,0,"upid",0
-4294967309,1409847216341006,"mem.mm.min_flt.max_lat",961.000000,0,"upid",0
-4294967310,1409847216341006,"mem.mm.min_flt.avg_lat",961.000000,0,"upid",0
-4294967311,1409847216341944,"mem.mm.min_flt.count",1.000000,0,"upid",0
-4294967312,1409847216341944,"mem.mm.min_flt.max_lat",889.000000,0,"upid",0
-4294967313,1409847216341944,"mem.mm.min_flt.avg_lat",889.000000,0,"upid",0
-4294967314,1409847218889548,"mem.mm.min_flt.count",1.000000,0,"upid",0
-4294967315,1409847218889548,"mem.mm.min_flt.max_lat",10.000000,0,"upid",0
-4294967316,1409847218889548,"mem.mm.min_flt.avg_lat",10.000000,0,"upid",0
-4294967317,1409847219001371,"mem.mm.min_flt.count",1.000000,0,"upid",0
-4294967318,1409847219001371,"mem.mm.min_flt.max_lat",66.000000,0,"upid",0
-4294967319,1409847219001371,"mem.mm.min_flt.avg_lat",66.000000,0,"upid",0
-4294967320,1409847352399457,"mem.mm.min_flt.count",12.000000,0,"upid",0
-4294967321,1409847352399457,"mem.mm.min_flt.max_lat",148.000000,0,"upid",0
-4294967322,1409847352399457,"mem.mm.min_flt.avg_lat",54.000000,0,"upid",0
-4294967323,1409847383618992,"mem.mm.min_flt.count",4.000000,0,"upid",0
-4294967324,1409847383618992,"mem.mm.min_flt.max_lat",34.000000,0,"upid",0
-4294967325,1409847383618992,"mem.mm.min_flt.avg_lat",21.000000,0,"upid",0
-4294967326,1409847431535611,"mem.mm.reclaim.count",1.000000,0,"upid",0
-4294967327,1409847431535611,"mem.mm.reclaim.max_lat",21.000000,0,"upid",0
-4294967328,1409847431535611,"mem.mm.reclaim.avg_lat",21.000000,0,"upid",0
-4294967329,1409847438281133,"mem.mm.compaction.count",1.000000,0,"upid",0
-4294967330,1409847438281133,"mem.mm.compaction.max_lat",6564.000000,0,"upid",0
-4294967331,1409847438281133,"mem.mm.compaction.avg_lat",6564.000000,0,"upid",0
-4294967332,1409847446501654,"mem.mm.min_flt.count",1.000000,0,"upid",0
-4294967333,1409847446501654,"mem.mm.min_flt.max_lat",12.000000,0,"upid",0
-4294967334,1409847446501654,"mem.mm.min_flt.avg_lat",12.000000,0,"upid",0
-4294967335,1409847447831498,"mem.mm.min_flt.count",1.000000,0,"upid",0
+"ts","name","value","ref","ref_type"
+1409847208580693,"mem.mm.min_flt.count",1.000000,0,"upid"
+1409847208580693,"mem.mm.min_flt.max_lat",9.000000,0,"upid"
+1409847208580693,"mem.mm.min_flt.avg_lat",9.000000,0,"upid"
+1409847209537724,"mem.mm.min_flt.count",1.000000,0,"upid"
+1409847209537724,"mem.mm.min_flt.max_lat",759.000000,0,"upid"
+1409847209537724,"mem.mm.min_flt.avg_lat",759.000000,0,"upid"
+1409847213761006,"mem.mm.min_flt.count",1.000000,0,"upid"
+1409847213761006,"mem.mm.min_flt.max_lat",10.000000,0,"upid"
+1409847213761006,"mem.mm.min_flt.avg_lat",10.000000,0,"upid"
+1409847214052256,"mem.mm.min_flt.count",1.000000,0,"upid"
+1409847214052256,"mem.mm.min_flt.max_lat",90.000000,0,"upid"
+1409847214052256,"mem.mm.min_flt.avg_lat",90.000000,0,"upid"
+1409847216341006,"mem.mm.min_flt.count",1.000000,0,"upid"
+1409847216341006,"mem.mm.min_flt.max_lat",961.000000,0,"upid"
+1409847216341006,"mem.mm.min_flt.avg_lat",961.000000,0,"upid"
+1409847216341944,"mem.mm.min_flt.count",1.000000,0,"upid"
+1409847216341944,"mem.mm.min_flt.max_lat",889.000000,0,"upid"
+1409847216341944,"mem.mm.min_flt.avg_lat",889.000000,0,"upid"
+1409847218889548,"mem.mm.min_flt.count",1.000000,0,"upid"
+1409847218889548,"mem.mm.min_flt.max_lat",10.000000,0,"upid"
+1409847218889548,"mem.mm.min_flt.avg_lat",10.000000,0,"upid"
+1409847219001371,"mem.mm.min_flt.count",1.000000,0,"upid"
+1409847219001371,"mem.mm.min_flt.max_lat",66.000000,0,"upid"
+1409847219001371,"mem.mm.min_flt.avg_lat",66.000000,0,"upid"
+1409847352399457,"mem.mm.min_flt.count",12.000000,0,"upid"
+1409847352399457,"mem.mm.min_flt.max_lat",148.000000,0,"upid"
+1409847352399457,"mem.mm.min_flt.avg_lat",54.000000,0,"upid"
+1409847383618992,"mem.mm.min_flt.count",4.000000,0,"upid"
+1409847383618992,"mem.mm.min_flt.max_lat",34.000000,0,"upid"
+1409847383618992,"mem.mm.min_flt.avg_lat",21.000000,0,"upid"
+1409847431535611,"mem.mm.reclaim.count",1.000000,0,"upid"
+1409847431535611,"mem.mm.reclaim.max_lat",21.000000,0,"upid"
+1409847431535611,"mem.mm.reclaim.avg_lat",21.000000,0,"upid"
+1409847438281133,"mem.mm.compaction.count",1.000000,0,"upid"
+1409847438281133,"mem.mm.compaction.max_lat",6564.000000,0,"upid"
+1409847438281133,"mem.mm.compaction.avg_lat",6564.000000,0,"upid"
+1409847446501654,"mem.mm.min_flt.count",1.000000,0,"upid"
+1409847446501654,"mem.mm.min_flt.max_lat",12.000000,0,"upid"
+1409847446501654,"mem.mm.min_flt.avg_lat",12.000000,0,"upid"
+1409847447831498,"mem.mm.min_flt.count",1.000000,0,"upid"
diff --git a/test/trace_processor/mm_event.sql b/test/trace_processor/mm_event.sql
index 187d0ff..e286c68 100644
--- a/test/trace_processor/mm_event.sql
+++ b/test/trace_processor/mm_event.sql
@@ -1,4 +1,4 @@
-select id, ts, name, value, ref, ref_type, arg_set_id
+select ts, name, value, ref, ref_type
from counters
where name like 'mem.mm.%'
order by ts
diff --git a/test/trace_processor/process_tracking_uid.out b/test/trace_processor/process_tracking_uid.out
new file mode 100644
index 0000000..ae90e8d
--- /dev/null
+++ b/test/trace_processor/process_tracking_uid.out
@@ -0,0 +1,6 @@
+"pid","uid"
+0,"[NULL]"
+10,1001
+20,1002
+30,"[NULL]"
+40,"[NULL]"
diff --git a/test/trace_processor/process_tracking_uid.sql b/test/trace_processor/process_tracking_uid.sql
new file mode 100644
index 0000000..de06399
--- /dev/null
+++ b/test/trace_processor/process_tracking_uid.sql
@@ -0,0 +1,3 @@
+select pid, uid
+from process
+order by pid;
diff --git a/test/trace_processor/synth_process_tracking.py b/test/trace_processor/synth_process_tracking.py
index 6686d89..a7a4d2d 100644
--- a/test/trace_processor/synth_process_tracking.py
+++ b/test/trace_processor/synth_process_tracking.py
@@ -40,7 +40,7 @@
# SQL level we should be able to tell that p1-t0 and p1-t2 belong to 'process1'
# but p1-t1 should be left unjoinable.
trace.add_process_tree_packet(ts=5)
-trace.add_process(10, 0, "process1")
+trace.add_process(10, 0, "process1", 1001)
trace.add_thread(12, 10, "p1-t2")
# Now create another process (pid=20) with three threads(tids=20,21,22).
@@ -58,7 +58,7 @@
# From the process tracker viewpoint we pretend we only scraped tids=20,21.
trace.add_process_tree_packet(ts=15)
-trace.add_process(20, 0, "process_2")
+trace.add_process(20, 0, "process_2", 1002)
trace.add_thread(21, 20, "p2-t1")
# Finally the very complex case: a third process (pid=30) which spawns threads
diff --git a/tools/tmux b/tools/tmux
index 035127f..0ab0349 100755
--- a/tools/tmux
+++ b/tools/tmux
@@ -24,7 +24,7 @@
function get_gn_value() {
local out=$1
local key=$2
- gn args "$out" --list --short | sed -n -e "s/$key = \"\(.*\)\"/\1/p"
+ gn args "$out" --list=$key --short | awk '{print $3}'
}
function is_monolithic() {
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 276f9d6..2d65f7a 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -241,15 +241,6 @@
"integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
"dev": true
},
- "agent-base": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
- "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
- "dev": true,
- "requires": {
- "es6-promisify": "^5.0.0"
- }
- },
"ajv": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz",
@@ -761,16 +752,6 @@
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
"dev": true
},
- "axios": {
- "version": "0.17.1",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.17.1.tgz",
- "integrity": "sha1-LY4+XQvb1zJ/kbyBT1xXZg+Bgk0=",
- "dev": true,
- "requires": {
- "follow-redirects": "^1.2.5",
- "is-buffer": "^1.1.5"
- }
- },
"babel-code-frame": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@@ -1178,13 +1159,13 @@
}
},
"browser-sync": {
- "version": "2.26.3",
- "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.26.3.tgz",
- "integrity": "sha512-VLzpjCA4uXqfzkwqWtMM6hvPm2PNHp2RcmzBXcbi6C9WpkUhhFb8SVAr4CFrCsFxDg+oY6HalOjn8F+egyvhag==",
+ "version": "2.26.7",
+ "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.26.7.tgz",
+ "integrity": "sha512-lY3emme0OyvA2ujEMpRmyRy9LY6gHLuTr2/ABxhIm3lADOiRXzP4dgekvnDrQqZ/Ec2Fz19lEjm6kglSG5766w==",
"dev": true,
"requires": {
- "browser-sync-client": "^2.26.2",
- "browser-sync-ui": "^2.26.2",
+ "browser-sync-client": "^2.26.6",
+ "browser-sync-ui": "^2.26.4",
"bs-recipes": "1.3.4",
"bs-snippet-injector": "^2.0.1",
"chokidar": "^2.0.4",
@@ -1198,8 +1179,8 @@
"fs-extra": "3.0.1",
"http-proxy": "1.15.2",
"immutable": "^3",
- "localtunnel": "1.9.1",
- "micromatch": "2.3.11",
+ "localtunnel": "1.9.2",
+ "micromatch": "^3.1.10",
"opn": "5.3.0",
"portscanner": "2.1.1",
"qs": "6.2.3",
@@ -1215,6 +1196,83 @@
"yargs": "6.4.0"
},
"dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "axios": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
+ "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==",
+ "dev": true,
+ "requires": {
+ "follow-redirects": "1.5.10",
+ "is-buffer": "^2.0.2"
+ }
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "browser-sync-client": {
+ "version": "2.26.6",
+ "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.26.6.tgz",
+ "integrity": "sha512-mGrkZdNzttKdf/16I+y+2dTQxoMCIpKbVIMJ/uP8ZpnKu9f9qa/2CYVtLtbjZG8nsM14EwiCrjuFTGBEnT3Gjw==",
+ "dev": true,
+ "requires": {
+ "etag": "1.8.1",
+ "fresh": "0.5.2",
+ "mitt": "^1.1.3",
+ "rxjs": "^5.5.6"
+ }
+ },
+ "browser-sync-ui": {
+ "version": "2.26.4",
+ "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.26.4.tgz",
+ "integrity": "sha512-u20P3EsZoM8Pt+puoi3BU3KlbQAH1lAcV+/O4saF26qokrBqIDotmGonfWwoRbUmdxZkM9MBmA0K39ZTG1h4sA==",
+ "dev": true,
+ "requires": {
+ "async-each-series": "0.1.1",
+ "connect-history-api-fallback": "^1",
+ "immutable": "^3",
+ "server-destroy": "1.0.1",
+ "socket.io-client": "^2.0.4",
+ "stream-throttle": "^0.1.3"
+ }
+ },
"camelcase": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
@@ -1232,6 +1290,244 @@
"wrap-ansi": "^2.0.0"
}
},
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "follow-redirects": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+ "dev": true,
+ "requires": {
+ "debug": "=3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-buffer": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
+ "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
+ "dev": true
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
@@ -1241,6 +1537,100 @@
"number-is-nan": "^1.0.0"
}
},
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "localtunnel": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.2.tgz",
+ "integrity": "sha512-NEKF7bDJE9U3xzJu3kbayF0WTvng6Pww7tzqNb/XtEARYwqw7CKEX7BvOMg98FtE9es2CRizl61gkV3hS8dqYg==",
+ "dev": true,
+ "requires": {
+ "axios": "0.19.0",
+ "debug": "4.1.1",
+ "openurl": "1.1.1",
+ "yargs": "6.6.0"
+ },
+ "dependencies": {
+ "yargs": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
+ "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^4.2.0"
+ }
+ }
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
"os-locale": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
@@ -1315,32 +1705,6 @@
}
}
},
- "browser-sync-client": {
- "version": "2.26.2",
- "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.26.2.tgz",
- "integrity": "sha512-FEuVJD41fI24HJ30XOT2RyF5WcnEtdJhhTqeyDlnMk/8Ox9MZw109rvk9pdfRWye4soZLe+xcAo9tHSMxvgAdw==",
- "dev": true,
- "requires": {
- "etag": "1.8.1",
- "fresh": "0.5.2",
- "mitt": "^1.1.3",
- "rxjs": "^5.5.6"
- }
- },
- "browser-sync-ui": {
- "version": "2.26.2",
- "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.26.2.tgz",
- "integrity": "sha512-LF7GMWo8ELOE0eAlxuRCfnGQT1ZxKP9flCfGgZdXFc6BwmoqaJHlYe7MmVvykKkXjolRXTz8ztXAKGVqNwJ3EQ==",
- "dev": true,
- "requires": {
- "async-each-series": "0.1.1",
- "connect-history-api-fallback": "^1",
- "immutable": "^3",
- "server-destroy": "1.0.1",
- "socket.io-client": "^2.0.4",
- "stream-throttle": "^0.1.3"
- }
- },
"bs-recipes": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz",
@@ -2503,32 +2867,6 @@
"locate-path": "^2.0.0"
}
},
- "follow-redirects": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz",
- "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==",
- "dev": true,
- "requires": {
- "debug": "^3.2.6"
- },
- "dependencies": {
- "debug": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
- "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "ms": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
- "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
- "dev": true
- }
- }
- },
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -2613,8 +2951,7 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -2657,8 +2994,7 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
@@ -2669,8 +3005,7 @@
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -2787,8 +3122,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -2800,7 +3134,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -2830,7 +3163,6 @@
"version": "2.3.5",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -2849,7 +3181,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -2943,7 +3274,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -3029,8 +3359,7 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -3066,7 +3395,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -3086,7 +3414,6 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -3130,14 +3457,12 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -3310,12 +3635,12 @@
"dev": true
},
"handlebars": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz",
- "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==",
+ "version": "4.5.3",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz",
+ "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==",
"dev": true,
"requires": {
- "async": "^2.5.0",
+ "neo-async": "^2.6.0",
"optimist": "^0.6.1",
"source-map": "^0.6.1",
"uglify-js": "^3.1.4"
@@ -3529,15 +3854,24 @@
}
},
"https-proxy-agent": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
- "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
+ "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
"dev": true,
"requires": {
- "agent-base": "^4.1.0",
+ "agent-base": "^4.3.0",
"debug": "^3.1.0"
},
"dependencies": {
+ "agent-base": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
+ "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
+ "dev": true,
+ "requires": {
+ "es6-promisify": "^5.0.0"
+ }
+ },
"debug": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
@@ -3548,9 +3882,9 @@
}
},
"ms": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
- "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
}
}
@@ -4445,9 +4779,9 @@
"dev": true
},
"js-yaml": {
- "version": "3.12.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz",
- "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==",
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
@@ -4628,111 +4962,6 @@
"strip-bom": "^2.0.0"
}
},
- "localtunnel": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.1.tgz",
- "integrity": "sha512-HWrhOslklDvxgOGFLxi6fQVnvpl6XdX4sPscfqMZkzi3gtt9V7LKBWYvNUcpHSVvjwCQ6xzXacVvICNbNcyPnQ==",
- "dev": true,
- "requires": {
- "axios": "0.17.1",
- "debug": "2.6.9",
- "openurl": "1.1.1",
- "yargs": "6.6.0"
- },
- "dependencies": {
- "camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
- "dev": true
- },
- "cliui": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
- "dev": true,
- "requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wrap-ansi": "^2.0.0"
- }
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "dev": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "os-locale": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
- "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
- "dev": true,
- "requires": {
- "lcid": "^1.0.0"
- }
- },
- "string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "dev": true,
- "requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "which-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
- "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
- "dev": true
- },
- "yargs": {
- "version": "6.6.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
- "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
- "dev": true,
- "requires": {
- "camelcase": "^3.0.0",
- "cliui": "^3.2.0",
- "decamelize": "^1.1.1",
- "get-caller-file": "^1.0.1",
- "os-locale": "^1.4.0",
- "read-pkg-up": "^1.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^1.0.1",
- "set-blocking": "^2.0.0",
- "string-width": "^1.0.2",
- "which-module": "^1.0.0",
- "y18n": "^3.2.1",
- "yargs-parser": "^4.2.0"
- }
- },
- "yargs-parser": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
- "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
- "dev": true,
- "requires": {
- "camelcase": "^3.0.0"
- }
- }
- }
- },
"locate-path": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
@@ -4744,9 +4973,9 @@
}
},
"lodash": {
- "version": "4.17.11",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
- "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
"lodash.isfinite": {
@@ -4959,9 +5188,9 @@
"dev": true
},
"mithril": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/mithril/-/mithril-1.1.6.tgz",
- "integrity": "sha512-fWcUrQTCqu8M916rj1MFGlHaPh65rznPu6U/N2U9g81H89klDCIptSK5bnkNkC+jyi3sJIXjyGhSQjUnR8jzZA=="
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/mithril/-/mithril-1.1.7.tgz",
+ "integrity": "sha512-1SAkGeVrIVvkUHlPHvR3pXdWzNfTzmS/fBAe+rC2ApEBfZFFc+idi8Qg/M5JoW/sZkIDXSfQYVgvENMIhBIVAg=="
},
"mitt": {
"version": "1.1.3",
@@ -4970,9 +5199,9 @@
"dev": true
},
"mixin-deep": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
- "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
"dev": true,
"requires": {
"for-in": "^1.0.2",
@@ -5077,6 +5306,12 @@
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
"dev": true
},
+ "neo-async": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
+ "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
+ "dev": true
+ },
"node-gyp": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
@@ -6542,288 +6777,19 @@
}
},
"rollup-pluginutils": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.7.1.tgz",
- "integrity": "sha512-3nRf3buQGR9qz/IsSzhZAJyoK663kzseps8itkYHr+Z7ESuaffEPfgRinxbCRA0pf0gzLqkNKkSb8aNVTq75NA==",
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
+ "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
"dev": true,
"requires": {
- "estree-walker": "^0.6.0",
- "micromatch": "^3.1.10"
+ "estree-walker": "^0.6.1"
},
"dependencies": {
- "arr-diff": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
- "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "estree-walker": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
+ "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
"dev": true
- },
- "array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
- "dev": true
- },
- "braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
- "dev": true,
- "requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "expand-brackets": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
- "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
- "dev": true,
- "requires": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
- "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-data-descriptor": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
- "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
- }
- },
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
- }
- },
- "extglob": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
- "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
- "dev": true,
- "requires": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- },
- "is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
- },
- "kind-of": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
- "dev": true
- },
- "micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
- "dev": true,
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
- }
}
}
},
@@ -7380,9 +7346,9 @@
"dev": true
},
"set-value": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
- "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
"dev": true,
"requires": {
"extend-shallow": "^2.0.1",
@@ -8280,38 +8246,15 @@
"dev": true
},
"union-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
- "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
"dev": true,
"requires": {
"arr-union": "^3.1.0",
"get-value": "^2.0.6",
"is-extendable": "^0.1.1",
- "set-value": "^0.4.3"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "set-value": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
- "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.1",
- "to-object-path": "^0.3.0"
- }
- }
+ "set-value": "^2.0.1"
}
},
"universalify": {
diff --git a/ui/package.json b/ui/package.json
index 7e3b8b5..e960062 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -24,7 +24,7 @@
"immer": "^1.12.1",
"jsbn-rsa": "^1.0.3",
"micromodal": "^0.4.0",
- "mithril": "^1.1.6",
+ "mithril": "^1.1.7",
"noice-json-rpc": "^1.2.0",
"pako": "^1.0.10",
"protobufjs": "^6.8.8",
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index 7edcbba..8c5fb67 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -302,7 +302,8 @@
//}
const maxCpuFreq = await engine.query(`
select max(value)
- from counters
+ from counter c
+ inner join cpu_counter_track t on c.track_id = t.id
where name = 'cpufreq';
`);
@@ -325,13 +326,28 @@
// cpu freq data.
// TODO(taylori): Find a way to display cpu idle
// events even if there are no cpu freq events.
- const freqExists = await engine.query(`
- select value
- from counters
- where name = 'cpufreq' and ref = ${cpu}
+ const cpuFreqIdle = await engine.query(`
+ select
+ id as cpu_freq_id,
+ (
+ select id
+ from cpu_counter_track
+ where name = 'cpuidle'
+ and cpu = ${cpu}
+ limit 1
+ ) as cpu_idle_id
+ from cpu_counter_track
+ where name = 'cpufreq' and cpu = ${cpu}
limit 1;
`);
- if (freqExists.numRecords > 0) {
+ if (cpuFreqIdle.numRecords > 0) {
+ const freqTrackId = +cpuFreqIdle.columns[0].longValues![0];
+
+ const idleTrackExists: boolean = !cpuFreqIdle.columns[1].isNulls![0];
+ const idleTrackId = idleTrackExists ?
+ +cpuFreqIdle.columns[1].longValues![0] :
+ undefined;
+
tracksToAdd.push({
engineId: this.engineId,
kind: CPU_FREQ_TRACK_KIND,
@@ -340,6 +356,8 @@
config: {
cpu,
maximumValue: +maxCpuFreq.columns[0].doubleValues![0],
+ freqTrackId,
+ idleTrackId,
}
});
}
@@ -414,46 +432,69 @@
}
}
-
- const counters = await engine.query(`
- select name, ref, ref_type
- from counter_definitions
- where ref is not null
- group by name, ref, ref_type
- order by ref_type desc
+ // Add global or GPU counter tracks that are not bound to any pid/tid.
+ const globalCounters = await engine.query(`
+ select name, id
+ from counter_track
+ where type = 'counter_track'
+ union
+ select name, id
+ from gpu_counter_track
+ where name != 'gpufreq'
`);
-
- interface CounterMap {
- [index: number]: string[];
+ for (let i = 0; i < globalCounters.numRecords; i++) {
+ const name = globalCounters.columns[0].stringValues![i];
+ const trackId = +globalCounters.columns[1].longValues![i];
+ tracksToAdd.push({
+ engineId: this.engineId,
+ kind: 'CounterTrack',
+ name,
+ trackGroup: SCROLLING_TRACK_GROUP,
+ config: {
+ name,
+ trackId,
+ }
+ });
}
- const counterUpids: CounterMap = new Array();
- const counterUtids: CounterMap = new Array();
- for (let i = 0; i < counters.numRecords; i++) {
- const name = counters.columns[0].stringValues![i];
- const ref = +counters.columns[1].longValues![i];
- const refType = counters.columns[2].stringValues![i];
- if (refType === 'upid') {
- const el = counterUpids[ref];
- el === undefined ? counterUpids[ref] = [name] :
- counterUpids[ref].push(name);
- } else if (refType === 'utid') {
- const el = counterUtids[ref];
- el === undefined ? counterUtids[ref] = [name] :
- counterUtids[ref].push(name);
- } else if (
- refType === '[NULL]' || (refType === 'gpu' && name !== 'gpufreq')) {
- // Add global or GPU counter tracks that are not bound to any pid/tid.
- tracksToAdd.push({
- engineId: this.engineId,
- kind: 'CounterTrack',
- name,
- trackGroup: SCROLLING_TRACK_GROUP,
- config: {
- name,
- ref: 0,
- }
- });
+ interface CounterTrack {
+ name: string;
+ trackId: number;
+ }
+
+ const counterUtids = new Map<number, CounterTrack[]>();
+ const threadCounters = await engine.query(`
+ select name, utid, id
+ from thread_counter_track
+ `);
+ for (let i = 0; i < threadCounters.numRecords; i++) {
+ const name = threadCounters.columns[0].stringValues![i];
+ const utid = +threadCounters.columns[1].longValues![i];
+ const trackId = +threadCounters.columns[2].longValues![i];
+
+ const el = counterUtids.get(utid);
+ if (el === undefined) {
+ counterUtids.set(utid, [{name, trackId}]);
+ } else {
+ el.push({name, trackId});
+ }
+ }
+
+ const counterUpids = new Map<number, CounterTrack[]>();
+ const processCounters = await engine.query(`
+ select name, upid, id
+ from process_counter_track
+ `);
+ for (let i = 0; i < processCounters.numRecords; i++) {
+ const name = processCounters.columns[0].stringValues![i];
+ const upid = +processCounters.columns[1].longValues![i];
+ const trackId = +processCounters.columns[2].longValues![i];
+
+ const el = counterUpids.get(upid);
+ if (el === undefined) {
+ counterUpids.set(upid, [{name, trackId}]);
+ } else {
+ el.push({name, trackId});
}
}
@@ -526,8 +567,8 @@
const threadTrack =
utid === null ? undefined : utidToThreadTrack.get(utid);
if (threadTrack === undefined &&
- (upid === null || counterUpids[upid] === undefined) &&
- counterUtids[utid] === undefined && !threadHasSched &&
+ (upid === null || counterUpids.get(upid) === undefined) &&
+ counterUtids.get(utid) === undefined && !threadHasSched &&
(upid === null || upid !== null && !heapUpids.has(upid))) {
continue;
}
@@ -571,18 +612,15 @@
}));
if (upid !== null) {
- const counterNames = counterUpids[upid];
+ const counterNames = counterUpids.get(upid);
if (counterNames !== undefined) {
counterNames.forEach(element => {
tracksToAdd.push({
engineId: this.engineId,
kind: 'CounterTrack',
- name: element,
+ name: element.name,
trackGroup: pUuid,
- config: {
- name: element,
- ref: upid,
- }
+ config: {name: element.name, trackId: element.trackId}
});
});
}
@@ -612,17 +650,17 @@
}
}
}
- const counterThreadNames = counterUtids[utid];
+ const counterThreadNames = counterUtids.get(utid);
if (counterThreadNames !== undefined) {
counterThreadNames.forEach(element => {
tracksToAdd.push({
engineId: this.engineId,
kind: 'CounterTrack',
- name: element,
+ name: element.name,
trackGroup: pUuid,
config: {
- name: element,
- ref: utid,
+ name: element.name,
+ trackId: element.trackId,
}
});
});
diff --git a/ui/src/frontend/flamegraph.ts b/ui/src/frontend/flamegraph.ts
index 5343a25..12b0785 100644
--- a/ui/src/frontend/flamegraph.ts
+++ b/ui/src/frontend/flamegraph.ts
@@ -77,14 +77,14 @@
return hash & 0xff;
}
- generateColor(name: string|undefined, isGreyedOut = false): string {
+ generateColor(name: string, isGreyedOut = false): string {
if (this.isThumbnail) {
return HEAP_PROFILE_COLOR;
}
if (isGreyedOut) {
return '#d9d9d9';
}
- if (name === undefined || name === 'root') {
+ if (name === 'unknown' || name === 'root') {
return '#c0c0c0';
}
const hue = this.hash(name);
@@ -161,7 +161,8 @@
currentY = nodeHeight * (value.depth + 1);
// Draw node.
- ctx.fillStyle = this.generateColor(value.name, isGreyedOut);
+ const name = this.getCallsiteName(value);
+ ctx.fillStyle = this.generateColor(name, isGreyedOut);
ctx.fillRect(currentX, currentY, width, nodeHeight);
// Set current node's data in map for children to use.
@@ -185,7 +186,6 @@
}
// Draw name.
- const name = this.getCallsiteName(value);
ctx.font = `${this.textSize}px Google Sans`;
const text = cropText(name, charWidth, width - 2);
ctx.fillStyle = 'black';
@@ -240,7 +240,8 @@
}
private getCallsiteName(value: CallsiteInfo): string {
- return value.name === undefined ? 'unknown' : value.name;
+ return value.name === undefined || value.name === '' ? 'unknown' :
+ value.name;
}
onMouseMove({x, y}: {x: number, y: number}) {
diff --git a/ui/src/tracks/counter/common.ts b/ui/src/tracks/counter/common.ts
index 0eb6dfb..53a603d 100644
--- a/ui/src/tracks/counter/common.ts
+++ b/ui/src/tracks/counter/common.ts
@@ -30,6 +30,6 @@
name: string;
maximumValue?: number;
minimumValue?: number;
- ref: number;
+ trackId: number;
scale?: 'DEFAULT'|'RELATIVE';
}
diff --git a/ui/src/tracks/counter/controller.ts b/ui/src/tracks/counter/controller.ts
index 4085845..0be0371 100644
--- a/ui/src/tracks/counter/controller.ts
+++ b/ui/src/tracks/counter/controller.ts
@@ -39,20 +39,22 @@
if (!this.setup) {
const result = await this.query(`
- select max(value), min(value) from
- counters where name = '${this.config.name}'
- and ref = ${this.config.ref}`);
+ select max(value), min(value)
+ from counter
+ where track_id = ${this.config.trackId}`);
this.maximumValueSeen = +result.columns[0].doubleValues![0];
this.minimumValueSeen = +result.columns[1].doubleValues![0];
await this.query(
`create virtual table ${this.tableName('window')} using window;`);
- await this.query(`create view ${this.tableName('counter_view')} as
- select ts,
- lead(ts, 1, ts) over (partition by ref_type order by ts) - ts as dur,
- value, name, ref
- from counters
- where name = '${this.config.name}' and ref = ${this.config.ref};`);
+ await this.query(`
+ create view ${this.tableName('counter_view')} as
+ select
+ ts,
+ lead(ts, 1, ts) over (order by ts) - ts as dur,
+ value
+ from counter
+ where track_id = ${this.config.trackId};`);
await this.query(`create virtual table ${this.tableName('span')} using
span_join(${this.tableName('counter_view')},
@@ -60,13 +62,16 @@
this.setup = true;
}
- const result = await this.engine.queryOneRow(`select count(*)
- from (select
- ts,
- lead(ts, 1, ts) over (partition by ref_type order by ts) as ts_end,
- from counters
- where name = '${this.config.name}' and ref = ${this.config.ref})
- where ts <= ${endNs} and ${startNs} <= ts_end`);
+ const result = await this.engine.queryOneRow(`
+ select count(*)
+ from (
+ select
+ ts,
+ lead(ts, 1, ts) over (order by ts) as ts_end,
+ from counter
+ where track_id = ${this.config.trackId}
+ )
+ where ts <= ${endNs} and ${startNs} <= ts_end`);
// Only quantize if we have too much data to draw.
const isQuantized = result[0] > LIMIT;
@@ -94,18 +99,32 @@
// Union that with the query that finds all the counters within
// the current query range.
query = `
- select * from (select ts, value, counter_id from counters
- where name = '${this.config.name}' and ref = ${this.config.ref} and
- ts <= ${startNs} order by ts desc limit 1)
- UNION
- select * from (select ts, value, counter_id
- from (select
- ts,
- lead(ts, 1, ts) over (partition by ref_type order by ts) as ts_end,
- value, counter_id
- from counters
- where name = '${this.config.name}' and ref = ${this.config.ref})
- where ts <= ${endNs} and ${startNs} <= ts_end limit ${LIMIT});`;
+ select *
+ from (
+ select ts, value, track_id
+ from counter
+ where
+ track_id = ${this.config.trackId} and
+ ts <= ${startNs}
+ order by ts desc
+ limit 1
+ )
+ union
+ select *
+ from (
+ select ts, value, track_id
+ from (
+ select
+ ts,
+ lead(ts, 1, ts) over (order by ts) as ts_end,
+ value,
+ track_id
+ from counter
+ where track_id = ${this.config.trackId}
+ )
+ where ts <= ${endNs} and ${startNs} <= ts_end
+ limit ${LIMIT}
+ );`;
}
const rawResult = await this.query(query);
diff --git a/ui/src/tracks/cpu_freq/common.ts b/ui/src/tracks/cpu_freq/common.ts
index 8968907..fff0c8f 100644
--- a/ui/src/tracks/cpu_freq/common.ts
+++ b/ui/src/tracks/cpu_freq/common.ts
@@ -28,5 +28,8 @@
export interface Config {
cpu: number;
+ freqTrackId: number;
+ idleTrackId?: number;
maximumValue?: number;
- minimumValue?: number;}
+ minimumValue?: number;
+}
diff --git a/ui/src/tracks/cpu_freq/controller.ts b/ui/src/tracks/cpu_freq/controller.ts
index 190a3d9..bdfbdae 100644
--- a/ui/src/tracks/cpu_freq/controller.ts
+++ b/ui/src/tracks/cpu_freq/controller.ts
@@ -38,9 +38,9 @@
if (!this.setup) {
const result = await this.query(`
- select max(value) from
- counters where name = 'cpufreq'
- and ref = ${this.config.cpu}`);
+ select max(value)
+ from counter
+ where track_id = ${this.config.freqTrackId}`);
this.maximumValueSeen = +result.columns[0].doubleValues![0];
await this.query(
@@ -49,36 +49,39 @@
await this.query(`create view ${this.tableName('freq')}
as select
ts,
- lead(ts) over (order by ts) - ts as dur,
- ref as cpu,
- name as freq_name,
+ lead(ts) over () - ts as dur,
value as freq_value
- from counters
- where name = 'cpufreq'
- and ref = ${this.config.cpu}
- and ref_type = 'cpu';
+ from counter c
+ where track_id = ${this.config.freqTrackId};
`);
- await this.query(`create view ${this.tableName('idle')}
- as select
- ts,
- lead(ts) over (order by ts) - ts as dur,
- ref as cpu,
- name as idle_name,
- value as idle_value
- from counters
- where name = 'cpuidle'
- and ref = ${this.config.cpu}
- and ref_type = 'cpu';
- `);
+ // If there is no idle track, just make the idle track a single row
+ // which spans the entire time range.
+ if (this.config.idleTrackId === undefined) {
+ await this.query(`create view ${this.tableName('idle')} as
+ select
+ 0 as ts,
+ ${Number.MAX_SAFE_INTEGER} as dur,
+ -1 as idle_value;
+ `);
+ } else {
+ await this.query(`create view ${this.tableName('idle')}
+ as select
+ ts,
+ lead(ts) over () - ts as dur,
+ value as idle_value
+ from counter c
+ where track_id = ${this.config.idleTrackId};
+ `);
+ }
await this.query(`create virtual table ${this.tableName('freq_idle')}
- using span_join(${this.tableName('freq')} PARTITIONED cpu,
- ${this.tableName('idle')} PARTITIONED cpu);`);
+ using span_join(${this.tableName('freq')},
+ ${this.tableName('idle')});`);
await this.query(`create virtual table ${this.tableName('span_activity')}
- using span_join(${this.tableName('freq_idle')} PARTITIONED cpu,
- ${this.tableName('window')});`);
+ using span_join(${this.tableName('freq_idle')},
+ ${this.tableName('window')});`);
// TODO(taylori): Move the idle value processing to the TP.
await this.query(`create view ${this.tableName('activity')}
@@ -86,7 +89,6 @@
ts,
dur,
quantum_ts,
- cpu,
case idle_value
when 4294967295 then -1
else idle_value
diff --git a/ui/src/tracks/heap_profile_flamegraph/controller.ts b/ui/src/tracks/heap_profile_flamegraph/controller.ts
index a0fbf9f..b84c688 100644
--- a/ui/src/tracks/heap_profile_flamegraph/controller.ts
+++ b/ui/src/tracks/heap_profile_flamegraph/controller.ts
@@ -362,24 +362,33 @@
this.tableName(`callsite_hash_name_size_${ts}`);
const tableNameGroupedCallsitesForFlamegraph =
this.tableName(`grouped_callsites_for_flamegraph${ts}`);
- // const tableNameGroupedCallsitesForFlamegraph =
- // this.tableNameGroupdCallsitesForFlamegraphAsKey(ts); Joining the callsite
- // table with frame table then with alloc table to get the size and name for
- // each callsite.
+ // Joining the callsite table with frame table then with alloc table to get
+ // the size and name for each callsite.
+ // TODO(tneda): Make frame name nullable in the trace processor for
+ // consistency with the other columns.
await this.query(`create view if not exists ${tableNameCallsiteNameSize} as
- select cs.id, parent_id, depth, IFNULL(symbols.name, fr.name) as name,
- SUM(IFNULL(size, 0)) as size,
- SUM(case when size > 0 then size else 0 end) as alloc_size,
- SUM(IFNULL(count, 0)) as count,
- SUM(case when count > 0 then count else 0 end) as alloc_count
- from stack_profile_callsite cs
- join stack_profile_frame fr on cs.frame_id = fr.id
- inner join (SELECT symbol_set_id, FIRST_VALUE(name) OVER(PARTITION BY
- symbol_set_id) as name
- FROM stack_profile_symbol GROUP BY symbol_set_id) as symbols
- using(symbol_set_id)
- left join heap_profile_allocation alloc on alloc.callsite_id = cs.id and
- alloc.ts <= ${ts} and alloc.upid = ${upid} group by cs.id`);
+ select id, parent_id, depth, IFNULL(DEMANGLE(name), name) as name,
+ map_name, size, alloc_size, count, alloc_count from (
+ select cs.id as id, parent_id, depth,
+ coalesce(symbols.name,
+ case when fr.name != '' then fr.name else map.name end) as name,
+ map.name as map_name,
+ SUM(IFNULL(size, 0)) as size,
+ SUM(IFNULL(size, 0)) as size,
+ SUM(case when size > 0 then size else 0 end) as alloc_size,
+ SUM(IFNULL(count, 0)) as count,
+ SUM(case when count > 0 then count else 0 end) as alloc_count
+ from stack_profile_callsite cs
+ join stack_profile_frame fr on cs.frame_id = fr.id
+ join stack_profile_mapping map on fr.mapping = map.id
+ inner join (
+ select symbol_set_id, FIRST_VALUE(name) OVER(PARTITION BY
+ symbol_set_id) as name
+ from stack_profile_symbol GROUP BY symbol_set_id
+ ) as symbols using(symbol_set_id)
+ left join heap_profile_allocation alloc on alloc.callsite_id = cs.id
+ and alloc.ts <= ${ts} and alloc.upid = ${upid} group by cs.id)`);
+
// Recursive query to compute the hash for each callsite based on names
// rather than ids.
// We get all the children of the row in question and emit a row with hash
@@ -421,7 +430,8 @@
tableNameGroupedCallsitesForFlamegraph}
as with recursive callsite_children(hash, name, parent_hash, depth,
size, alloc_size, count, alloc_count) AS (
- select *
+ select hash, name, parent_hash, depth, size, alloc_size,
+ count, alloc_count
from ${tableNameCallsiteHashNameSize}
union all
select chns.hash, chns.name, chns.parent_hash, chns.depth, cc.size,