Skip to content

Commit 7728787

Browse files
tomekzawmeta-codesync[bot]
authored andcommitted
Emit C++ TraceSection markers through ATrace on Android (#59065)
Summary: `TraceSection` (`ReactCommon/cxxreact/TraceSection.h`) is the C++ tracing primitive used throughout the renderer: `ShadowTree::commit`, `UIManager::createNode`, the Yoga measure callbacks, `FabricMountingManager::executeMount` and others. On Android it only does something when built with `WITH_PERFETTO` or `WITH_FBSYSTRACE`, and the OSS build sets neither, so it compiles to `DummyTraceSection`. **Current behavior.** Perfetto and systrace captures of OSS Android apps show only the Java/Kotlin sections. The C++ half of the renderer (commit, layout, text measurement, building mount instructions) is invisible. **With this change.** A new Android branch calls the NDK's `ATrace_beginSection` and `ATrace_endSection`: - It includes `<android/trace.h>` and calls the NDK functions directly. They exist from API 23, and React Native's `minSdk` is 24. `libreactnative` already links `libandroid`, and `libhermestooling` gets it through `libreactnative`, so no build changes are needed. - Each section checks `ATrace_isEnabled()` first, so when nobody is tracing it costs one call. - `WITH_PERFETTO` and `WITH_FBSYSTRACE` keep precedence. - Section arguments (key/value pairs) are ignored for now. **Why.** Without this, profiling React Native on Android with standard tools can't show where commit and layout time goes. In a capture of RNTester mounting a 100-post feed, this branch shows 7084 `UIManager::createNode` sections and 1632 Yoga measure-callback sections, among others; on `main` none of them appear. ## Changelog: [ANDROID] [ADDED] - C++ `TraceSection` markers now appear in Perfetto and systrace captures Pull Request resolved: #59065 Test Plan: - RNTester `assembleDebug` and `assembleRelease` (`-PreactNativeArchitectures=arm64-v8a`) and `yarn format-check-cpp` pass. - Recorded Perfetto traces (`atrace_apps: "com.facebook.react.uiapp"`) of the same RNTester scenario on `main` and on this branch. The C++ sections appear only on this branch. - Rebuilt after switching to direct calls: `libreactnative.so` imports the three `ATrace_*` functions from `libandroid.so`, and a Perfetto capture of an RNTester release launch on a physical device shows the C++ sections (`UIManager::createNode`, `ShadowTree::commit`, `FabricMountingManager::executeMount`, ...). - **Overhead with tracing off** (measured on the first revision, which looked the functions up with `dlsym`; direct calls do the same work minus the null checks). Emulator (Pixel 10 Pro AVD, API 37), release builds, current `main` vs. this branch, 6 runs, medians: | scenario | total CPU, main | total CPU, this PR | change | |---|--:|--:|--:| | mount 100-post feed | 128.8 ms | 130.0 ms | +1% | | mount 1000 labels | 117.7 ms | 117.1 ms | −1% | Update phases were within emulator noise, with mixed signs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: javache Differential Revision: D125730780 Pulled By: Abbondanzo fbshipit-source-id: bba4bc9a4b191f7dd1acc67925df51d379f97745
1 parent 65b3e64 commit 7728787

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

‎packages/react-native/ReactCommon/cxxreact/TraceSection.h‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
#include <reactperflogger/ReactPerfettoCategories.h>
3535
#endif
3636

37+
#if defined(__ANDROID__) && __ANDROID_API__ >= 23 && !defined(WITH_PERFETTO) && !defined(WITH_FBSYSTRACE)
38+
#include <android/trace.h>
39+
#endif
40+
3741
#if defined(__APPLE__)
3842
// This is required so that OS_LOG_TARGET_HAS_10_15_FEATURES will be set.
3943
#include <os/trace_base.h>
@@ -95,6 +99,34 @@ struct ConcreteTraceSection {
9599
fbsystrace::FbSystraceSection m_section;
96100
};
97101
using TraceSectionUnwrapped = ConcreteTraceSection;
102+
#elif defined(__ANDROID__) && __ANDROID_API__ >= 23
103+
// Route TraceSection to the platform ATrace API so
104+
// that C++ sections show up in Perfetto/systrace captures of OSS builds.
105+
struct ATraceSection {
106+
public:
107+
template <typename... ConvertsToStringPiece>
108+
explicit ATraceSection(const char *name, [[maybe_unused]] ConvertsToStringPiece &&...args)
109+
{
110+
if (ATrace_isEnabled()) {
111+
ATrace_beginSection(name);
112+
active_ = true;
113+
}
114+
}
115+
116+
~ATraceSection()
117+
{
118+
if (active_) {
119+
ATrace_endSection();
120+
}
121+
}
122+
123+
ATraceSection(const ATraceSection &) = delete;
124+
ATraceSection &operator=(const ATraceSection &) = delete;
125+
126+
private:
127+
bool active_{false};
128+
};
129+
using TraceSectionUnwrapped = ATraceSection;
98130
#else
99131
struct DummyTraceSection {
100132
public:

0 commit comments

Comments
 (0)