Merge "Client library: make code gc-sections friendly"
diff --git a/Android.bp b/Android.bp
index 0768acc..0b1651b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -478,7 +478,7 @@
":perfetto_src_ipc_common",
":perfetto_src_ipc_host",
":perfetto_src_protozero_protozero",
- ":perfetto_src_tracing_client_api_base",
+ ":perfetto_src_tracing_client_api_without_backends",
":perfetto_src_tracing_common",
":perfetto_src_tracing_core_core",
":perfetto_src_tracing_core_service",
@@ -488,7 +488,7 @@
":perfetto_src_tracing_ipc_producer_producer",
":perfetto_src_tracing_ipc_service_service",
":perfetto_src_tracing_platform_posix",
- ":perfetto_src_tracing_system_process_backend",
+ ":perfetto_src_tracing_system_backend",
],
export_include_dirs: [
"include",
@@ -1362,7 +1362,7 @@
":perfetto_src_traced_probes_probes_src",
":perfetto_src_traced_probes_ps_ps",
":perfetto_src_traced_probes_sys_stats_sys_stats",
- ":perfetto_src_tracing_client_api_base",
+ ":perfetto_src_tracing_client_api_without_backends",
":perfetto_src_tracing_common",
":perfetto_src_tracing_core_core",
":perfetto_src_tracing_core_service",
@@ -1372,7 +1372,7 @@
":perfetto_src_tracing_ipc_producer_producer",
":perfetto_src_tracing_ipc_service_service",
":perfetto_src_tracing_platform_posix",
- ":perfetto_src_tracing_system_process_backend",
+ ":perfetto_src_tracing_system_backend",
":perfetto_src_tracing_test_api_test_support",
":perfetto_src_tracing_test_client_api_integrationtests",
":perfetto_test_end_to_end_integrationtests",
@@ -6508,9 +6508,9 @@
],
}
-// GN: //src/tracing:client_api_base
+// GN: //src/tracing:client_api_without_backends
filegroup {
- name: "perfetto_src_tracing_client_api_base",
+ name: "perfetto_src_tracing_client_api_without_backends",
srcs: [
"src/tracing/data_source.cc",
"src/tracing/debug_annotation.cc",
@@ -6655,9 +6655,9 @@
],
}
-// GN: //src/tracing:system_process_backend
+// GN: //src/tracing:system_backend
filegroup {
- name: "perfetto_src_tracing_system_process_backend",
+ name: "perfetto_src_tracing_system_backend",
srcs: [
"src/tracing/internal/system_tracing_backend.cc",
],
diff --git a/BUILD b/BUILD
index e1f060e..82d6dba 100644
--- a/BUILD
+++ b/BUILD
@@ -475,6 +475,8 @@
"include/perfetto/tracing/event_context.h",
"include/perfetto/tracing/internal/basic_types.h",
"include/perfetto/tracing/internal/data_source_internal.h",
+ "include/perfetto/tracing/internal/in_process_tracing_backend.h",
+ "include/perfetto/tracing/internal/system_tracing_backend.h",
"include/perfetto/tracing/internal/tracing_muxer.h",
"include/perfetto/tracing/internal/tracing_tls.h",
"include/perfetto/tracing/internal/track_event_data_source.h",
@@ -1222,15 +1224,13 @@
],
)
-# GN target: //src/tracing:client_api_base
+# GN target: //src/tracing:client_api_without_backends
filegroup(
- name = "src_tracing_client_api_base",
+ name = "src_tracing_client_api_without_backends",
srcs = [
"src/tracing/data_source.cc",
"src/tracing/debug_annotation.cc",
"src/tracing/event_context.cc",
- "src/tracing/internal/in_process_tracing_backend.h",
- "src/tracing/internal/system_tracing_backend.h",
"src/tracing/internal/tracing_muxer_impl.cc",
"src/tracing/internal/tracing_muxer_impl.h",
"src/tracing/internal/track_event_internal.cc",
@@ -1267,9 +1267,9 @@
],
)
-# GN target: //src/tracing:system_process_backend
+# GN target: //src/tracing:system_backend
filegroup(
- name = "src_tracing_system_process_backend",
+ name = "src_tracing_system_backend",
srcs = [
"src/tracing/internal/system_tracing_backend.cc",
],
@@ -2482,7 +2482,7 @@
":src_ipc_common",
":src_ipc_host",
":src_protozero_protozero",
- ":src_tracing_client_api_base",
+ ":src_tracing_client_api_without_backends",
":src_tracing_common",
":src_tracing_core_core",
":src_tracing_core_service",
@@ -2492,7 +2492,7 @@
":src_tracing_ipc_producer_producer",
":src_tracing_ipc_service_service",
":src_tracing_platform_posix",
- ":src_tracing_system_process_backend",
+ ":src_tracing_system_backend",
],
hdrs = [
":include_perfetto_base_base",
diff --git a/BUILD.gn b/BUILD.gn
index 6972e58..e9e51ec 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -211,19 +211,9 @@
complete_static_lib = true
public_deps = [
"gn:default_deps",
+ "src/tracing:client_api",
"src/tracing:platform_posix",
- "src/tracing/core",
]
-
- # TODO(primiano): in Android this target should be split in full / light,
- # where light depends on client_api_system_backend_only instead of
- # client_api (see r.android.com/1218897).
- # The full client_api is too big binary-size-wise for production (see
- # b/148198993). However, tests want to use the full library because having
- # an in-house service is more convenient.
- # As a stop-gap solution to b/148517641 we re-link the full library by
- # default in Android.
- public_deps += [ "src/tracing:client_api" ]
sources = [ "include/perfetto/tracing.h" ]
assert_no_deps = [ "//gn:protobuf_lite" ]
}
diff --git a/include/perfetto/tracing/BUILD.gn b/include/perfetto/tracing/BUILD.gn
index e6c68c4..78216fa 100644
--- a/include/perfetto/tracing/BUILD.gn
+++ b/include/perfetto/tracing/BUILD.gn
@@ -30,6 +30,8 @@
"event_context.h",
"internal/basic_types.h",
"internal/data_source_internal.h",
+ "internal/in_process_tracing_backend.h",
+ "internal/system_tracing_backend.h",
"internal/tracing_muxer.h",
"internal/tracing_tls.h",
"internal/track_event_data_source.h",
diff --git a/src/tracing/internal/in_process_tracing_backend.h b/include/perfetto/tracing/internal/in_process_tracing_backend.h
similarity index 85%
rename from src/tracing/internal/in_process_tracing_backend.h
rename to include/perfetto/tracing/internal/in_process_tracing_backend.h
index 8d07ae7..4e36588 100644
--- a/src/tracing/internal/in_process_tracing_backend.h
+++ b/include/perfetto/tracing/internal/in_process_tracing_backend.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef SRC_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
-#define SRC_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
#include "perfetto/tracing/tracing_backend.h"
@@ -36,7 +36,7 @@
// use-cases.
class InProcessTracingBackend : public TracingBackend {
public:
- static InProcessTracingBackend* GetInstance();
+ static TracingBackend* GetInstance();
// TracingBackend implementation.
std::unique_ptr<ProducerEndpoint> ConnectProducer(
@@ -54,4 +54,4 @@
} // namespace internal
} // namespace perfetto
-#endif // SRC_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
+#endif // INCLUDE_PERFETTO_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
diff --git a/src/tracing/internal/system_tracing_backend.h b/include/perfetto/tracing/internal/system_tracing_backend.h
similarity index 86%
rename from src/tracing/internal/system_tracing_backend.h
rename to include/perfetto/tracing/internal/system_tracing_backend.h
index ca70242..aaa694f 100644
--- a/src/tracing/internal/system_tracing_backend.h
+++ b/include/perfetto/tracing/internal/system_tracing_backend.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef SRC_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
-#define SRC_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
#include "perfetto/tracing/tracing_backend.h"
@@ -36,7 +36,7 @@
namespace internal {
class SystemTracingBackend : public TracingBackend {
public:
- static SystemTracingBackend* GetInstance();
+ static TracingBackend* GetInstance();
// TracingBackend implementation.
std::unique_ptr<ProducerEndpoint> ConnectProducer(
@@ -51,4 +51,4 @@
} // namespace internal
} // namespace perfetto
-#endif // SRC_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
+#endif // INCLUDE_PERFETTO_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
diff --git a/include/perfetto/tracing/tracing.h b/include/perfetto/tracing/tracing.h
index 61e805c..8d2dc59 100644
--- a/include/perfetto/tracing/tracing.h
+++ b/include/perfetto/tracing/tracing.h
@@ -25,11 +25,19 @@
#include <string>
#include <vector>
+#include "perfetto/base/compiler.h"
#include "perfetto/base/export.h"
#include "perfetto/base/logging.h"
#include "perfetto/tracing/core/forward_decls.h"
+#include "perfetto/tracing/internal/in_process_tracing_backend.h"
+#include "perfetto/tracing/internal/system_tracing_backend.h"
+
namespace perfetto {
+namespace internal {
+class TracingMuxerImpl;
+}
+
class TracingBackend;
class Platform;
class TracingSession; // Declared below.
@@ -75,16 +83,25 @@
// Must be one of [4, 8, 16, 32].
uint32_t shmem_page_size_hint_kb = 0;
- bool operator==(const TracingInitArgs& other) const {
- return std::tie(backends, custom_backend, platform, shmem_size_hint_kb,
- shmem_page_size_hint_kb, dcheck_is_on_) ==
- std::tie(other.backends, other.custom_backend, other.platform,
- other.shmem_size_hint_kb, other.shmem_page_size_hint_kb,
- other.dcheck_is_on_);
- }
-
protected:
friend class Tracing;
+ friend class internal::TracingMuxerImpl;
+
+ // Used only by the DCHECK in tracing.cc, to check that the config is the
+ // same in case of re-initialization.
+ bool operator==(const TracingInitArgs& other) const {
+ return std::tie(backends, custom_backend, platform, shmem_size_hint_kb,
+ shmem_page_size_hint_kb, in_process_backend_factory_,
+ system_backend_factory_, dcheck_is_on_) ==
+ std::tie(other.backends, other.custom_backend, other.platform,
+ other.shmem_size_hint_kb, other.shmem_page_size_hint_kb,
+ other.in_process_backend_factory_,
+ other.system_backend_factory_, other.dcheck_is_on_);
+ }
+
+ using BackendFactoryFunction = TracingBackend* (*)();
+ BackendFactoryFunction in_process_backend_factory_ = nullptr;
+ BackendFactoryFunction system_backend_factory_ = nullptr;
bool dcheck_is_on_ = PERFETTO_DCHECK_IS_ON();
};
@@ -93,7 +110,30 @@
public:
// Initializes Perfetto with the given backends in the calling process and/or
// with a user-provided backend. No-op if called more than once.
- static void Initialize(const TracingInitArgs&);
+ static inline void Initialize(const TracingInitArgs& args)
+ PERFETTO_ALWAYS_INLINE {
+ TracingInitArgs args_copy(args);
+ // This code is inlined to allow dead-code elimination for unused backends.
+ // This saves ~200 KB when not using the in-process backend (b/148198993).
+ // The logic behind it is the following:
+ // Nothing other than the code below references the two GetInstance()
+ // methods. From a linker-graph viewpoint, those GetInstance() pull in many
+ // other pieces of the codebase (e.g. InProcessTracingBackend pulls the
+ // whole TracingServiceImpl, SystemTracingBackend pulls the whole //ipc
+ // layer). Due to the inline, the compiler can see through the code and
+ // realize that some branches are always not taken. When that happens, no
+ // reference to the backends' GetInstance() is emitted and that allows the
+ // linker GC to get rid of the entire set of dependencies.
+ if (args.backends & kInProcessBackend) {
+ args_copy.in_process_backend_factory_ =
+ &internal::InProcessTracingBackend::GetInstance;
+ }
+ if (args.backends & kSystemBackend) {
+ args_copy.system_backend_factory_ =
+ &internal::SystemTracingBackend::GetInstance;
+ }
+ InitializeInternal(args_copy);
+ }
// Start a new tracing session using the given tracing backend. Use
// |kUnspecifiedBackend| to select an available backend automatically.
@@ -103,6 +143,8 @@
BackendType = kUnspecifiedBackend);
private:
+ static void InitializeInternal(const TracingInitArgs&);
+
Tracing() = delete;
};
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index fed1820..fb24c7b 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -19,49 +19,31 @@
# Full version of the client API. Supports both the in-process backend and the
# system backend (on posix systems and if enabled by the enable_perfetto_ipc).
-# It has a larger binary footprint due to the service code for the in-proecss
-# backend.
+# The backends are designed to be dead-code-eliminated via linker's gc-section
+# when not use. See comments in Tracing::Initialize() in tracing.h.
group("client_api") {
public_deps = [
- ":client_api_base",
+ ":client_api_without_backends",
+ ":in_process_backend",
"../../gn:default_deps",
+ "../../include/perfetto/tracing",
+ "../../include/perfetto/tracing/core",
]
- deps = [ ":in_process_backend" ]
if (enable_perfetto_ipc) {
- deps += [ ":system_process_backend" ]
- } else {
- deps += [ ":system_process_backend_fake" ]
+ public_deps += [ ":system_backend" ]
}
}
-# Slim version of the client API. Works only with the system backend (traced
-# connection over a UNIX socket). Has a lighter binary size impact.
-if (enable_perfetto_ipc) {
- source_set("client_api_system_backend_only") {
- public_deps = [
- ":client_api_base",
- "../../gn:default_deps",
- ]
- deps = [
- ":in_process_backend_fake",
- ":system_process_backend",
- ]
- }
-}
-
-# This target checks only that the "fake" backends compile. This is to detect
-# early if we break them with refactorings, without waiting for TreeHugger or
-# rolls into chromium.
+# This target checks that the client API builds without backends. This is to
+# check that no references to the backends are leaked from the implementation
+# internals. In turn, this allows to dead-code-eliminate unused backends when
+# using linker's gc-sections (or similar mechanism).
if (perfetto_build_standalone) {
shared_library("client_api_no_backends_compile_test") {
- public_deps = [
- ":client_api_base",
- "../../gn:default_deps",
- ]
deps = [
- ":in_process_backend_fake",
+ ":client_api_without_backends",
":platform_fake",
- ":system_process_backend_fake",
+ "../../gn:default_deps",
]
}
}
@@ -101,7 +83,7 @@
}
# Base target for the client API. On its own doesn't provide any backend.
-source_set("client_api_base") {
+source_set("client_api_without_backends") {
deps = [
"../../include/perfetto/tracing/core",
"../../protos/perfetto/config:cpp",
@@ -116,8 +98,6 @@
"data_source.cc",
"debug_annotation.cc",
"event_context.cc",
- "internal/in_process_tracing_backend.h",
- "internal/system_tracing_backend.h",
"internal/tracing_muxer_impl.cc",
"internal/tracing_muxer_impl.h",
"internal/track_event_internal.cc",
@@ -128,15 +108,22 @@
"track_event_legacy.cc",
"virtual_destructors.cc",
]
+ assert_no_deps = [ "core:service" ]
+ if (enable_perfetto_ipc) {
+ assert_no_deps += [
+ "../ipc:common",
+ "ipc/common",
+ ]
+ }
}
# System backend: connects to an external "traced" instance via a UNIX socket.
# Requires the IPC layer and is supported only on posix systems.
if (enable_perfetto_ipc) {
- source_set("system_process_backend") {
+ source_set("system_backend") {
public_deps = [ "../../include/perfetto/tracing" ]
deps = [
- ":client_api_base",
+ ":client_api_without_backends",
"../../gn:default_deps",
"../../include/perfetto/tracing/core",
"../base",
@@ -148,24 +135,13 @@
}
}
-# System backend fallback: it prints an error message and returns nullptr.
-source_set("system_process_backend_fake") {
- public_deps = [ "../../include/perfetto/tracing" ]
- deps = [
- ":client_api_base",
- "../../gn:default_deps",
- "../base",
- ]
- sources = [ "internal/system_tracing_backend_fake.cc" ]
-}
-
# In-process backend: starts the tracing service in-process on a dedicated
# thread. It depends only on having a valid "platform" target. It has a larger
# binary size cost because links in all the service code.
source_set("in_process_backend") {
public_deps = [ "../../include/perfetto/tracing" ]
deps = [
- ":client_api_base",
+ ":client_api_without_backends",
"../../gn:default_deps",
"../../include/perfetto/tracing/core",
"../base",
@@ -173,14 +149,3 @@
]
sources = [ "internal/in_process_tracing_backend.cc" ]
}
-
-# In-process backend fallback: it prints an error messaage and returns nullptr.
-source_set("in_process_backend_fake") {
- public_deps = [ "../../include/perfetto/tracing" ]
- deps = [
- ":client_api_base",
- "../../gn:default_deps",
- "../base",
- ]
- sources = [ "internal/in_process_tracing_backend_fake.cc" ]
-}
diff --git a/src/tracing/internal/in_process_tracing_backend.cc b/src/tracing/internal/in_process_tracing_backend.cc
index 7f6d350..1df0f4b 100644
--- a/src/tracing/internal/in_process_tracing_backend.cc
+++ b/src/tracing/internal/in_process_tracing_backend.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/tracing/internal/in_process_tracing_backend.h"
+#include "perfetto/tracing/internal/in_process_tracing_backend.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
@@ -75,7 +75,7 @@
} // namespace
// static
-InProcessTracingBackend* InProcessTracingBackend::GetInstance() {
+TracingBackend* InProcessTracingBackend::GetInstance() {
static auto* instance = new InProcessTracingBackend();
return instance;
}
diff --git a/src/tracing/internal/in_process_tracing_backend_fake.cc b/src/tracing/internal/in_process_tracing_backend_fake.cc
deleted file mode 100644
index 7ffafa8..0000000
--- a/src/tracing/internal/in_process_tracing_backend_fake.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/tracing/internal/in_process_tracing_backend.h"
-
-#include "perfetto/base/logging.h"
-
-namespace perfetto {
-namespace internal {
-
-// static
-InProcessTracingBackend* InProcessTracingBackend::GetInstance() {
- PERFETTO_ELOG(
- "In-process tracing backend not supported by the current build "
- "configuration");
- return nullptr;
-}
-
-} // namespace internal
-} // namespace perfetto
diff --git a/src/tracing/internal/system_tracing_backend.cc b/src/tracing/internal/system_tracing_backend.cc
index d8e89f2..987f956 100644
--- a/src/tracing/internal/system_tracing_backend.cc
+++ b/src/tracing/internal/system_tracing_backend.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/tracing/internal/system_tracing_backend.h"
+#include "perfetto/tracing/internal/system_tracing_backend.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
@@ -26,7 +26,7 @@
namespace internal {
// static
-SystemTracingBackend* SystemTracingBackend::GetInstance() {
+TracingBackend* SystemTracingBackend::GetInstance() {
static auto* instance = new SystemTracingBackend();
return instance;
}
diff --git a/src/tracing/internal/system_tracing_backend_fake.cc b/src/tracing/internal/system_tracing_backend_fake.cc
deleted file mode 100644
index 6a940ae..0000000
--- a/src/tracing/internal/system_tracing_backend_fake.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/tracing/internal/system_tracing_backend.h"
-
-#include "perfetto/base/logging.h"
-
-namespace perfetto {
-namespace internal {
-
-// static
-SystemTracingBackend* SystemTracingBackend::GetInstance() {
- PERFETTO_ELOG(
- "System tracing backend not supported by the current build "
- "configuration");
- return nullptr;
-}
-
-} // namespace internal
-} // namespace perfetto
diff --git a/src/tracing/internal/tracing_muxer_impl.cc b/src/tracing/internal/tracing_muxer_impl.cc
index e63bc11..b9b9f08 100644
--- a/src/tracing/internal/tracing_muxer_impl.cc
+++ b/src/tracing/internal/tracing_muxer_impl.cc
@@ -37,8 +37,6 @@
#include "perfetto/tracing/trace_writer_base.h"
#include "perfetto/tracing/tracing.h"
#include "perfetto/tracing/tracing_backend.h"
-#include "src/tracing/internal/in_process_tracing_backend.h"
-#include "src/tracing/internal/system_tracing_backend.h"
namespace perfetto {
namespace internal {
@@ -443,15 +441,15 @@
rb.producer->Initialize(rb.backend->ConnectProducer(conn_args));
};
- // Both the system and the in-process backends can be disabled at build-time
- // and replaced with the _fake.cc versions. The "fake" versions will just
- // ELOG() and return nullptr.
+ if (args.backends & kSystemBackend) {
+ PERFETTO_CHECK(args.system_backend_factory_);
+ add_backend(args.system_backend_factory_(), kSystemBackend);
+ }
- if (args.backends & kSystemBackend)
- add_backend(SystemTracingBackend::GetInstance(), kSystemBackend);
-
- if (args.backends & kInProcessBackend)
- add_backend(InProcessTracingBackend::GetInstance(), kInProcessBackend);
+ if (args.backends & kInProcessBackend) {
+ PERFETTO_CHECK(args.in_process_backend_factory_);
+ add_backend(args.in_process_backend_factory_(), kInProcessBackend);
+ }
if (args.backends & kCustomBackend) {
PERFETTO_CHECK(args.custom_backend);
diff --git a/src/tracing/tracing.cc b/src/tracing/tracing.cc
index 8b20b7f..c0149d9 100644
--- a/src/tracing/tracing.cc
+++ b/src/tracing/tracing.cc
@@ -24,7 +24,7 @@
namespace perfetto {
// static
-void Tracing::Initialize(const TracingInitArgs& args) {
+void Tracing::InitializeInternal(const TracingInitArgs& args) {
static bool was_initialized = false;
static TracingInitArgs init_args;
if (was_initialized) {