react-native 0.83.4 → 0.83.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Utilities/Appearance.js +6 -1
- package/Libraries/Utilities/HMRClient.js +28 -1
- package/React/Base/RCTVersion.m +1 -1
- package/React/CoreModules/RCTDevLoadingView.mm +17 -0
- package/React/DevSupport/RCTFrameTimingsObserver.h +24 -0
- package/React/DevSupport/RCTFrameTimingsObserver.mm +298 -0
- package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +16 -0
- package/ReactAndroid/api/ReactAndroid.api +0 -9
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgelessDevSupportManager.kt +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.kt +7 -7
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorFlags.kt +4 -0
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingSequence.kt +16 -0
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt +275 -0
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/TracingState.kt +17 -0
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/TracingStateListener.kt +15 -0
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/{interfaces → inspector}/TracingStateProvider.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorInspectorTargetBinding.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorOverlayManager.kt +4 -4
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorOverlayView.kt +3 -3
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorUpdateListener.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +13 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +21 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +5 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +5 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +23 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +5 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/tracing/PerformanceTracer.kt +39 -0
- package/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobModule.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkEventUtil.kt +20 -19
- package/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.kt +6 -12
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +86 -4
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImplDevHelper.kt +3 -3
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostInspectorTarget.kt +10 -6
- package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.cpp +22 -0
- package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.h +2 -0
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +29 -1
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +7 -1
- package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.cpp +196 -17
- package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h +168 -18
- package/ReactAndroid/src/main/jni/third-party/folly/CMakeLists.txt +1 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
- package/ReactCommon/hermes/inspector-modern/chrome/Registration.cpp +44 -2
- package/ReactCommon/jsinspector-modern/HostAgent.cpp +45 -10
- package/ReactCommon/jsinspector-modern/HostAgent.h +2 -2
- package/ReactCommon/jsinspector-modern/HostTarget.cpp +14 -7
- package/ReactCommon/jsinspector-modern/HostTarget.h +101 -14
- package/ReactCommon/jsinspector-modern/HostTargetTraceRecording.cpp +39 -8
- package/ReactCommon/jsinspector-modern/HostTargetTraceRecording.h +42 -5
- package/ReactCommon/jsinspector-modern/HostTargetTracing.cpp +54 -21
- package/ReactCommon/jsinspector-modern/HostTargetTracing.h +89 -0
- package/ReactCommon/jsinspector-modern/InspectorFlags.cpp +12 -0
- package/ReactCommon/jsinspector-modern/InspectorFlags.h +12 -0
- package/ReactCommon/jsinspector-modern/InspectorInterfaces.cpp +3 -7
- package/ReactCommon/jsinspector-modern/InstanceAgent.cpp +2 -11
- package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +1 -1
- package/ReactCommon/jsinspector-modern/RuntimeAgent.cpp +19 -0
- package/ReactCommon/jsinspector-modern/RuntimeAgent.h +7 -0
- package/ReactCommon/jsinspector-modern/RuntimeTarget.cpp +33 -0
- package/ReactCommon/jsinspector-modern/RuntimeTarget.h +6 -0
- package/ReactCommon/jsinspector-modern/TracingAgent.cpp +29 -13
- package/ReactCommon/jsinspector-modern/TracingAgent.h +5 -4
- package/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +65 -0
- package/ReactCommon/jsinspector-modern/tests/InspectorMocks.h +23 -2
- package/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp +1 -0
- package/ReactCommon/jsinspector-modern/tests/NetworkReporterTest.cpp +1 -0
- package/ReactCommon/jsinspector-modern/tests/TracingTest.cpp +335 -0
- package/ReactCommon/jsinspector-modern/tests/TracingTest.h +95 -0
- package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.cpp +10 -0
- package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h +3 -1
- package/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt +1 -0
- package/ReactCommon/jsinspector-modern/tracing/FrameTimingSequence.h +61 -0
- package/ReactCommon/jsinspector-modern/tracing/HostTracingProfile.h +43 -0
- package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.cpp +165 -0
- package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.h +50 -0
- package/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp +16 -14
- package/ReactCommon/jsinspector-modern/tracing/PerformanceTracerSection.h +113 -0
- package/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +1 -0
- package/ReactCommon/jsinspector-modern/tracing/TimeWindowedBuffer.h +158 -0
- package/ReactCommon/jsinspector-modern/tracing/TraceEvent.h +2 -1
- package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.cpp +100 -0
- package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.h +60 -0
- package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.cpp +44 -1
- package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.h +7 -0
- package/ReactCommon/jsinspector-modern/tracing/TraceRecordingState.h +18 -7
- package/ReactCommon/jsinspector-modern/tracing/TracingCategory.h +136 -0
- package/ReactCommon/jsinspector-modern/tracing/tests/TimeWindowedBufferTest.cpp +352 -0
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +9 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +11 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +65 -29
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +6 -2
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +9 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +19 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +3 -1
- package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +3 -1
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +11 -1
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +5 -1
- package/ReactCommon/react/performance/timeline/PerformanceObserver.cpp +18 -6
- package/ReactCommon/react/performance/timeline/PerformanceObserver.h +2 -0
- package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +115 -0
- package/ReactCommon/{jsinspector-modern → react/utils}/Base64.h +2 -2
- package/gradle/libs.versions.toml +1 -1
- package/package.json +10 -10
- package/scripts/cocoapods/utils.rb +1 -0
- package/src/private/featureflags/ReactNativeFeatureFlags.js +11 -1
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +3 -1
- package/third-party-podspecs/RCT-Folly.podspec +1 -1
- package/third-party-podspecs/fmt.podspec +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/TracingState.kt +0 -19
- package/ReactCommon/jsinspector-modern/tracing/TraceRecordingStateSerializer.cpp +0 -68
- package/ReactCommon/jsinspector-modern/tracing/TraceRecordingStateSerializer.h +0 -42
- package/ReactCommon/jsinspector-modern/tracing/TracingState.h +0 -24
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "HostTracingProfileSerializer.h"
|
|
9
|
+
#include "RuntimeSamplingProfileTraceEventSerializer.h"
|
|
10
|
+
#include "TraceEventGenerator.h"
|
|
11
|
+
#include "TraceEventSerializer.h"
|
|
12
|
+
|
|
13
|
+
namespace facebook::react::jsinspector_modern::tracing {
|
|
14
|
+
|
|
15
|
+
namespace {
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Hardcoded layer tree ID for all recorded frames.
|
|
19
|
+
* https://chromedevtools.github.io/devtools-protocol/tot/LayerTree/
|
|
20
|
+
*/
|
|
21
|
+
constexpr int FALLBACK_LAYER_TREE_ID = 1;
|
|
22
|
+
|
|
23
|
+
} // namespace
|
|
24
|
+
|
|
25
|
+
/* static */ void HostTracingProfileSerializer::emitAsDataCollectedChunks(
|
|
26
|
+
HostTracingProfile&& hostTracingProfile,
|
|
27
|
+
const std::function<void(folly::dynamic&&)>& chunkCallback,
|
|
28
|
+
size_t maxChunkBytes,
|
|
29
|
+
uint16_t profileTraceEventsChunkSize) {
|
|
30
|
+
emitFrameTimings(
|
|
31
|
+
std::move(hostTracingProfile.frameTimings),
|
|
32
|
+
hostTracingProfile.processId,
|
|
33
|
+
hostTracingProfile.startTime,
|
|
34
|
+
chunkCallback,
|
|
35
|
+
maxChunkBytes);
|
|
36
|
+
|
|
37
|
+
auto instancesProfiles =
|
|
38
|
+
std::move(hostTracingProfile.instanceTracingProfiles);
|
|
39
|
+
IdGenerator profileIdGenerator;
|
|
40
|
+
|
|
41
|
+
for (auto& instanceProfile : instancesProfiles) {
|
|
42
|
+
emitPerformanceTraceEvents(
|
|
43
|
+
std::move(instanceProfile.performanceTraceEvents),
|
|
44
|
+
chunkCallback,
|
|
45
|
+
maxChunkBytes);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
RuntimeSamplingProfileTraceEventSerializer::serializeAndDispatch(
|
|
49
|
+
std::move(hostTracingProfile.runtimeSamplingProfiles),
|
|
50
|
+
profileIdGenerator,
|
|
51
|
+
hostTracingProfile.startTime,
|
|
52
|
+
chunkCallback,
|
|
53
|
+
profileTraceEventsChunkSize);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* static */ void HostTracingProfileSerializer::emitPerformanceTraceEvents(
|
|
57
|
+
std::vector<TraceEvent>&& events,
|
|
58
|
+
const std::function<void(folly::dynamic&&)>& chunkCallback,
|
|
59
|
+
size_t maxChunkBytes) {
|
|
60
|
+
folly::dynamic chunk = folly::dynamic::array();
|
|
61
|
+
size_t currentChunkBytes = 0;
|
|
62
|
+
|
|
63
|
+
for (auto& event : events) {
|
|
64
|
+
auto serializedEvent = TraceEventSerializer::serialize(std::move(event));
|
|
65
|
+
size_t eventBytes = TraceEventSerializer::estimateJsonSize(serializedEvent);
|
|
66
|
+
|
|
67
|
+
if (currentChunkBytes + eventBytes > maxChunkBytes && !chunk.empty()) {
|
|
68
|
+
chunkCallback(std::move(chunk));
|
|
69
|
+
chunk = folly::dynamic::array();
|
|
70
|
+
currentChunkBytes = 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
chunk.push_back(std::move(serializedEvent));
|
|
74
|
+
currentChunkBytes += eventBytes;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!chunk.empty()) {
|
|
78
|
+
chunkCallback(std::move(chunk));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* static */ void HostTracingProfileSerializer::emitFrameTimings(
|
|
83
|
+
std::vector<FrameTimingSequence>&& frameTimings,
|
|
84
|
+
ProcessId processId,
|
|
85
|
+
HighResTimeStamp recordingStartTimestamp,
|
|
86
|
+
const std::function<void(folly::dynamic&& chunk)>& chunkCallback,
|
|
87
|
+
size_t maxChunkBytes) {
|
|
88
|
+
if (frameTimings.empty()) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
folly::dynamic chunk = folly::dynamic::array();
|
|
93
|
+
size_t currentChunkBytes = 0;
|
|
94
|
+
|
|
95
|
+
auto setLayerTreeIdEvent = TraceEventGenerator::createSetLayerTreeIdEvent(
|
|
96
|
+
"", // Hardcoded frame name for the default (and only) layer.
|
|
97
|
+
FALLBACK_LAYER_TREE_ID,
|
|
98
|
+
processId,
|
|
99
|
+
frameTimings.front().threadId,
|
|
100
|
+
recordingStartTimestamp);
|
|
101
|
+
auto serializedSetLayerTreeId =
|
|
102
|
+
TraceEventSerializer::serialize(std::move(setLayerTreeIdEvent));
|
|
103
|
+
currentChunkBytes +=
|
|
104
|
+
TraceEventSerializer::estimateJsonSize(serializedSetLayerTreeId);
|
|
105
|
+
chunk.push_back(std::move(serializedSetLayerTreeId));
|
|
106
|
+
|
|
107
|
+
for (auto&& frameTimingSequence : frameTimings) {
|
|
108
|
+
// Serialize all events for this frame.
|
|
109
|
+
folly::dynamic frameEvents = folly::dynamic::array();
|
|
110
|
+
size_t totalFrameBytes = 0;
|
|
111
|
+
|
|
112
|
+
auto [beginDrawingEvent, endDrawingEvent] =
|
|
113
|
+
TraceEventGenerator::createFrameTimingsEvents(
|
|
114
|
+
frameTimingSequence.id,
|
|
115
|
+
FALLBACK_LAYER_TREE_ID,
|
|
116
|
+
frameTimingSequence.beginTimestamp,
|
|
117
|
+
frameTimingSequence.endTimestamp,
|
|
118
|
+
processId,
|
|
119
|
+
frameTimingSequence.threadId);
|
|
120
|
+
|
|
121
|
+
auto serializedBegin =
|
|
122
|
+
TraceEventSerializer::serialize(std::move(beginDrawingEvent));
|
|
123
|
+
totalFrameBytes += TraceEventSerializer::estimateJsonSize(serializedBegin);
|
|
124
|
+
frameEvents.push_back(std::move(serializedBegin));
|
|
125
|
+
|
|
126
|
+
auto serializedEnd =
|
|
127
|
+
TraceEventSerializer::serialize(std::move(endDrawingEvent));
|
|
128
|
+
totalFrameBytes += TraceEventSerializer::estimateJsonSize(serializedEnd);
|
|
129
|
+
frameEvents.push_back(std::move(serializedEnd));
|
|
130
|
+
|
|
131
|
+
if (frameTimingSequence.screenshot.has_value()) {
|
|
132
|
+
auto screenshotEvent = TraceEventGenerator::createScreenshotEvent(
|
|
133
|
+
frameTimingSequence.id,
|
|
134
|
+
FALLBACK_LAYER_TREE_ID,
|
|
135
|
+
std::move(frameTimingSequence.screenshot.value()),
|
|
136
|
+
frameTimingSequence.endTimestamp,
|
|
137
|
+
processId,
|
|
138
|
+
frameTimingSequence.threadId);
|
|
139
|
+
|
|
140
|
+
auto serializedScreenshot =
|
|
141
|
+
TraceEventSerializer::serialize(std::move(screenshotEvent));
|
|
142
|
+
totalFrameBytes +=
|
|
143
|
+
TraceEventSerializer::estimateJsonSize(serializedScreenshot);
|
|
144
|
+
frameEvents.push_back(std::move(serializedScreenshot));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Flush current chunk if adding this frame would exceed the limit.
|
|
148
|
+
if (currentChunkBytes + totalFrameBytes > maxChunkBytes && !chunk.empty()) {
|
|
149
|
+
chunkCallback(std::move(chunk));
|
|
150
|
+
chunk = folly::dynamic::array();
|
|
151
|
+
currentChunkBytes = 0;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
for (auto& frameEvent : frameEvents) {
|
|
155
|
+
chunk.push_back(std::move(frameEvent));
|
|
156
|
+
}
|
|
157
|
+
currentChunkBytes += totalFrameBytes;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (!chunk.empty()) {
|
|
161
|
+
chunkCallback(std::move(chunk));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
} // namespace facebook::react::jsinspector_modern::tracing
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include "FrameTimingSequence.h"
|
|
11
|
+
#include "HostTracingProfile.h"
|
|
12
|
+
#include "TraceEvent.h"
|
|
13
|
+
|
|
14
|
+
#include <folly/dynamic.h>
|
|
15
|
+
#include <vector>
|
|
16
|
+
|
|
17
|
+
namespace facebook::react::jsinspector_modern::tracing {
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A serializer for HostTracingProfile that can be used for transforming the
|
|
21
|
+
* profile into sequence of serialized Trace Events.
|
|
22
|
+
*/
|
|
23
|
+
class HostTracingProfileSerializer {
|
|
24
|
+
public:
|
|
25
|
+
/**
|
|
26
|
+
* Transforms the profile into a sequence of serialized Trace Events, which
|
|
27
|
+
* is split in chunks of at most \p maxChunkBytes serialized bytes or
|
|
28
|
+
* \p profileTraceEventsChunkSize events, depending on type, and sent with
|
|
29
|
+
* \p chunkCallback.
|
|
30
|
+
*/
|
|
31
|
+
static void emitAsDataCollectedChunks(
|
|
32
|
+
HostTracingProfile &&hostTracingProfile,
|
|
33
|
+
const std::function<void(folly::dynamic &&chunk)> &chunkCallback,
|
|
34
|
+
size_t maxChunkBytes,
|
|
35
|
+
uint16_t profileTraceEventsChunkSize);
|
|
36
|
+
|
|
37
|
+
static void emitPerformanceTraceEvents(
|
|
38
|
+
std::vector<TraceEvent> &&events,
|
|
39
|
+
const std::function<void(folly::dynamic &&chunk)> &chunkCallback,
|
|
40
|
+
size_t maxChunkBytes);
|
|
41
|
+
|
|
42
|
+
static void emitFrameTimings(
|
|
43
|
+
std::vector<FrameTimingSequence> &&frameTimings,
|
|
44
|
+
ProcessId processId,
|
|
45
|
+
HighResTimeStamp recordingStartTimestamp,
|
|
46
|
+
const std::function<void(folly::dynamic &&chunk)> &chunkCallback,
|
|
47
|
+
size_t maxChunkBytes);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
} // namespace facebook::react::jsinspector_modern::tracing
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
#include "PerformanceTracer.h"
|
|
9
9
|
#include "Timing.h"
|
|
10
|
+
#include "TraceEventGenerator.h"
|
|
10
11
|
#include "TraceEventSerializer.h"
|
|
12
|
+
#include "TracingCategory.h"
|
|
11
13
|
|
|
12
14
|
#include <jsinspector-modern/network/CdpNetwork.h>
|
|
13
15
|
#include <jsinspector-modern/network/HttpUtils.h>
|
|
@@ -138,7 +140,7 @@ std::optional<std::vector<TraceEvent>> PerformanceTracer::stopTracing() {
|
|
|
138
140
|
events.emplace_back(
|
|
139
141
|
TraceEvent{
|
|
140
142
|
.name = "TracingStartedInPage",
|
|
141
|
-
.cat =
|
|
143
|
+
.cat = {Category::HiddenTimeline},
|
|
142
144
|
.ph = 'I',
|
|
143
145
|
.ts = currentTraceStartTime,
|
|
144
146
|
.pid = processId_,
|
|
@@ -149,7 +151,7 @@ std::optional<std::vector<TraceEvent>> PerformanceTracer::stopTracing() {
|
|
|
149
151
|
events.emplace_back(
|
|
150
152
|
TraceEvent{
|
|
151
153
|
.name = "ReactNative-TracingStopped",
|
|
152
|
-
.cat =
|
|
154
|
+
.cat = {Category::HiddenTimeline},
|
|
153
155
|
.ph = 'I',
|
|
154
156
|
.ts = currentTraceEndTime,
|
|
155
157
|
.pid = processId_,
|
|
@@ -370,7 +372,7 @@ void PerformanceTracer::reportResourceFinish(
|
|
|
370
372
|
return TraceEvent{
|
|
371
373
|
.id = profileId,
|
|
372
374
|
.name = "Profile",
|
|
373
|
-
.cat =
|
|
375
|
+
.cat = {Category::JavaScriptSampling},
|
|
374
376
|
.ph = 'P',
|
|
375
377
|
.ts = profileTimestamp,
|
|
376
378
|
.pid = processId,
|
|
@@ -393,7 +395,7 @@ PerformanceTracer::constructRuntimeProfileChunkTraceEvent(
|
|
|
393
395
|
return TraceEvent{
|
|
394
396
|
.id = profileId,
|
|
395
397
|
.name = "ProfileChunk",
|
|
396
|
-
.cat =
|
|
398
|
+
.cat = {Category::JavaScriptSampling},
|
|
397
399
|
.ph = 'P',
|
|
398
400
|
.ts = chunkTimestamp,
|
|
399
401
|
.pid = processId,
|
|
@@ -525,7 +527,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
|
|
|
525
527
|
events.emplace_back(
|
|
526
528
|
TraceEvent{
|
|
527
529
|
.name = "RunTask",
|
|
528
|
-
.cat =
|
|
530
|
+
.cat = {Category::HiddenTimeline},
|
|
529
531
|
.ph = 'X',
|
|
530
532
|
.ts = event.start,
|
|
531
533
|
.pid = processId_,
|
|
@@ -537,7 +539,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
|
|
|
537
539
|
events.emplace_back(
|
|
538
540
|
TraceEvent{
|
|
539
541
|
.name = "RunMicrotasks",
|
|
540
|
-
.cat =
|
|
542
|
+
.cat = {Category::RuntimeExecution},
|
|
541
543
|
.ph = 'X',
|
|
542
544
|
.ts = event.start,
|
|
543
545
|
.pid = processId_,
|
|
@@ -557,7 +559,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
|
|
|
557
559
|
events.emplace_back(
|
|
558
560
|
TraceEvent{
|
|
559
561
|
.name = std::move(event.name),
|
|
560
|
-
.cat =
|
|
562
|
+
.cat = {Category::UserTiming},
|
|
561
563
|
.ph = 'I',
|
|
562
564
|
.ts = event.start,
|
|
563
565
|
.pid = processId_,
|
|
@@ -578,7 +580,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
|
|
|
578
580
|
TraceEvent{
|
|
579
581
|
.id = eventId,
|
|
580
582
|
.name = event.name,
|
|
581
|
-
.cat =
|
|
583
|
+
.cat = {Category::UserTiming},
|
|
582
584
|
.ph = 'b',
|
|
583
585
|
.ts = event.start,
|
|
584
586
|
.pid = processId_,
|
|
@@ -589,7 +591,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
|
|
|
589
591
|
TraceEvent{
|
|
590
592
|
.id = eventId,
|
|
591
593
|
.name = std::move(event.name),
|
|
592
|
-
.cat =
|
|
594
|
+
.cat = {Category::UserTiming},
|
|
593
595
|
.ph = 'e',
|
|
594
596
|
.ts = event.start + event.duration,
|
|
595
597
|
.pid = processId_,
|
|
@@ -629,7 +631,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
|
|
|
629
631
|
events.emplace_back(
|
|
630
632
|
TraceEvent{
|
|
631
633
|
.name = "TimeStamp",
|
|
632
|
-
.cat =
|
|
634
|
+
.cat = {Category::Timeline},
|
|
633
635
|
.ph = 'I',
|
|
634
636
|
.ts = event.createdAt,
|
|
635
637
|
.pid = processId_,
|
|
@@ -664,7 +666,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
|
|
|
664
666
|
events.emplace_back(
|
|
665
667
|
TraceEvent{
|
|
666
668
|
.name = "TimeStamp",
|
|
667
|
-
.cat =
|
|
669
|
+
.cat = {Category::Timeline},
|
|
668
670
|
.ph = 'I',
|
|
669
671
|
.ts = event.createdAt,
|
|
670
672
|
.pid = processId_,
|
|
@@ -684,7 +686,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
|
|
|
684
686
|
events.emplace_back(
|
|
685
687
|
TraceEvent{
|
|
686
688
|
.name = "ResourceSendRequest",
|
|
687
|
-
.cat =
|
|
689
|
+
.cat = {Category::Timeline},
|
|
688
690
|
.ph = 'I',
|
|
689
691
|
.ts = event.start,
|
|
690
692
|
.pid = processId_,
|
|
@@ -710,7 +712,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
|
|
|
710
712
|
events.emplace_back(
|
|
711
713
|
TraceEvent{
|
|
712
714
|
.name = "ResourceReceiveResponse",
|
|
713
|
-
.cat =
|
|
715
|
+
.cat = {Category::Timeline},
|
|
714
716
|
.ph = 'I',
|
|
715
717
|
.ts = event.start,
|
|
716
718
|
.pid = processId_,
|
|
@@ -728,7 +730,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
|
|
|
728
730
|
events.emplace_back(
|
|
729
731
|
TraceEvent{
|
|
730
732
|
.name = "ResourceFinish",
|
|
731
|
-
.cat =
|
|
733
|
+
.cat = {Category::Timeline},
|
|
732
734
|
.ph = 'I',
|
|
733
735
|
.ts = event.start,
|
|
734
736
|
.pid = processId_,
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <folly/dynamic.h>
|
|
11
|
+
|
|
12
|
+
#include <jsinspector-modern/tracing/PerformanceTracer.h>
|
|
13
|
+
|
|
14
|
+
#include <string_view>
|
|
15
|
+
|
|
16
|
+
namespace facebook::react::jsinspector_modern::tracing {
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This is a RAII class that reports a timeStamp block to the React Native
|
|
20
|
+
* Performance Tracer.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* {
|
|
24
|
+
* PerformanceTracerSection s("name", "track", "track group");
|
|
25
|
+
* // do something
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
template <typename... Args>
|
|
29
|
+
class PerformanceTracerSection {
|
|
30
|
+
public:
|
|
31
|
+
explicit PerformanceTracerSection(
|
|
32
|
+
const char *name,
|
|
33
|
+
const char *track = nullptr,
|
|
34
|
+
const char *trackGroup = nullptr,
|
|
35
|
+
const char *color = nullptr,
|
|
36
|
+
Args... args) noexcept
|
|
37
|
+
: name_(name), track_(track), trackGroup_(trackGroup), color_(color), args_(std::move(args)...)
|
|
38
|
+
{
|
|
39
|
+
static_assert(
|
|
40
|
+
sizeof...(Args) % 2 == 0,
|
|
41
|
+
"PerformanceTracerSection expects an even number of variadic args representing [name, value] pairs.");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Non-movable
|
|
45
|
+
PerformanceTracerSection(const PerformanceTracerSection &) = delete;
|
|
46
|
+
PerformanceTracerSection(PerformanceTracerSection &&) = delete;
|
|
47
|
+
|
|
48
|
+
// Non-copyable
|
|
49
|
+
PerformanceTracerSection &operator=(const PerformanceTracerSection &) = delete;
|
|
50
|
+
PerformanceTracerSection &operator=(PerformanceTracerSection &&) = delete;
|
|
51
|
+
|
|
52
|
+
~PerformanceTracerSection() noexcept
|
|
53
|
+
{
|
|
54
|
+
auto &tracer = PerformanceTracer::getInstance();
|
|
55
|
+
if (!tracer.isTracing()) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
auto endTime = HighResTimeStamp::now();
|
|
60
|
+
|
|
61
|
+
// Slow path when passing properties
|
|
62
|
+
if constexpr (sizeof...(Args) > 0) {
|
|
63
|
+
auto properties = folly::dynamic::array();
|
|
64
|
+
std::apply(
|
|
65
|
+
[&](const auto &...elems) {
|
|
66
|
+
size_t idx = 0;
|
|
67
|
+
(((idx % 2 == 0) ? properties.push_back(folly::dynamic::array(elems))
|
|
68
|
+
: properties[properties.size() - 1].push_back(elems),
|
|
69
|
+
++idx),
|
|
70
|
+
...);
|
|
71
|
+
},
|
|
72
|
+
args_);
|
|
73
|
+
|
|
74
|
+
folly::dynamic devtools = folly::dynamic::object();
|
|
75
|
+
devtools["properties"] = std::move(properties);
|
|
76
|
+
|
|
77
|
+
if (track_ != nullptr) {
|
|
78
|
+
devtools["track"] = track_;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (trackGroup_ != nullptr) {
|
|
82
|
+
devtools["trackGroup"] = trackGroup_;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (color_ != nullptr) {
|
|
86
|
+
devtools["color"] = color_;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
folly::dynamic detail = folly::dynamic::object();
|
|
90
|
+
detail["devtools"] = std::move(devtools);
|
|
91
|
+
|
|
92
|
+
tracer.reportMeasure(std::string(name_), startTime_, endTime - startTime_, std::move(detail));
|
|
93
|
+
} else {
|
|
94
|
+
tracer.reportTimeStamp(
|
|
95
|
+
std::string(name_),
|
|
96
|
+
startTime_,
|
|
97
|
+
endTime,
|
|
98
|
+
track_ != nullptr ? std::optional{track_} : std::nullopt,
|
|
99
|
+
trackGroup_ != nullptr ? std::optional{trackGroup_} : std::nullopt,
|
|
100
|
+
color_ != nullptr ? getConsoleTimeStampColorFromString(color_) : std::nullopt);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private:
|
|
105
|
+
HighResTimeStamp startTime_{HighResTimeStamp::now()};
|
|
106
|
+
std::string_view name_;
|
|
107
|
+
const char *track_;
|
|
108
|
+
const char *trackGroup_;
|
|
109
|
+
const char *color_;
|
|
110
|
+
std::tuple<Args...> args_;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
} // namespace facebook::react::jsinspector_modern::tracing
|
|
@@ -47,6 +47,7 @@ Pod::Spec.new do |s|
|
|
|
47
47
|
s.dependency "React-jsi"
|
|
48
48
|
s.dependency "React-oscompat"
|
|
49
49
|
s.dependency "React-timing"
|
|
50
|
+
add_dependency(s, "React-utils", :additional_framework_paths => ["react/utils/platform/ios"])
|
|
50
51
|
|
|
51
52
|
if use_hermes()
|
|
52
53
|
s.dependency "hermes-engine"
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <algorithm>
|
|
11
|
+
#include <functional>
|
|
12
|
+
#include <optional>
|
|
13
|
+
#include <vector>
|
|
14
|
+
|
|
15
|
+
#include <react/timing/primitives.h>
|
|
16
|
+
|
|
17
|
+
namespace facebook::react::jsinspector_modern::tracing {
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The currentBufferStartTime_ is initialized once first element is pushed.
|
|
21
|
+
*/
|
|
22
|
+
constexpr HighResTimeStamp kCurrentBufferStartTimeUninitialized = HighResTimeStamp::min();
|
|
23
|
+
|
|
24
|
+
template <typename T>
|
|
25
|
+
class TimeWindowedBuffer {
|
|
26
|
+
public:
|
|
27
|
+
using TimestampAccessor = std::function<HighResTimeStamp(const T &)>;
|
|
28
|
+
|
|
29
|
+
TimeWindowedBuffer() : timestampAccessor_(std::nullopt), windowSize_(std::nullopt) {}
|
|
30
|
+
|
|
31
|
+
TimeWindowedBuffer(TimestampAccessor timestampAccessor, HighResDuration windowSize)
|
|
32
|
+
: timestampAccessor_(std::move(timestampAccessor)), windowSize_(windowSize)
|
|
33
|
+
{
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
void push(const T &element)
|
|
37
|
+
{
|
|
38
|
+
if (timestampAccessor_) {
|
|
39
|
+
auto timestamp = (*timestampAccessor_)(element);
|
|
40
|
+
enqueueElement(element, timestamp);
|
|
41
|
+
} else {
|
|
42
|
+
enqueueElement(element, HighResTimeStamp::now());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
void push(T &&element)
|
|
47
|
+
{
|
|
48
|
+
if (timestampAccessor_) {
|
|
49
|
+
auto timestamp = (*timestampAccessor_)(element);
|
|
50
|
+
enqueueElement(std::move(element), timestamp);
|
|
51
|
+
} else {
|
|
52
|
+
enqueueElement(std::move(element), HighResTimeStamp::now());
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void clear()
|
|
57
|
+
{
|
|
58
|
+
primaryBuffer_.clear();
|
|
59
|
+
alternativeBuffer_.clear();
|
|
60
|
+
currentBufferIndex_ = BufferIndex::Primary;
|
|
61
|
+
currentBufferStartTime_ = kCurrentBufferStartTimeUninitialized;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Forces immediate removal of elements that are outside the time window.
|
|
66
|
+
* The right boundary of the window is the reference timestamp passed as an argument.
|
|
67
|
+
*/
|
|
68
|
+
std::vector<T> pruneExpiredAndExtract(HighResTimeStamp windowRightBoundary = HighResTimeStamp::now())
|
|
69
|
+
{
|
|
70
|
+
std::vector<T> result;
|
|
71
|
+
|
|
72
|
+
for (auto &wrappedElement : getPreviousBuffer()) {
|
|
73
|
+
if (isInsideTimeWindow(wrappedElement, windowRightBoundary)) {
|
|
74
|
+
result.push_back(std::move(wrappedElement.element));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
for (auto &wrappedElement : getCurrentBuffer()) {
|
|
79
|
+
if (isInsideTimeWindow(wrappedElement, windowRightBoundary)) {
|
|
80
|
+
result.push_back(std::move(wrappedElement.element));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
clear();
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private:
|
|
89
|
+
enum class BufferIndex { Primary, Alternative };
|
|
90
|
+
|
|
91
|
+
struct TimestampedElement {
|
|
92
|
+
T element;
|
|
93
|
+
HighResTimeStamp timestamp;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
std::vector<TimestampedElement> &getCurrentBuffer()
|
|
97
|
+
{
|
|
98
|
+
return currentBufferIndex_ == BufferIndex::Primary ? primaryBuffer_ : alternativeBuffer_;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
std::vector<TimestampedElement> &getPreviousBuffer()
|
|
102
|
+
{
|
|
103
|
+
return currentBufferIndex_ == BufferIndex::Primary ? alternativeBuffer_ : primaryBuffer_;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
void enqueueElement(const T &element, HighResTimeStamp timestamp)
|
|
107
|
+
{
|
|
108
|
+
if (windowSize_) {
|
|
109
|
+
if (currentBufferStartTime_ == kCurrentBufferStartTimeUninitialized) {
|
|
110
|
+
currentBufferStartTime_ = timestamp;
|
|
111
|
+
} else if (timestamp > currentBufferStartTime_ + *windowSize_) {
|
|
112
|
+
// We moved past the current buffer. We need to switch the other buffer as current.
|
|
113
|
+
currentBufferIndex_ =
|
|
114
|
+
currentBufferIndex_ == BufferIndex::Primary ? BufferIndex::Alternative : BufferIndex::Primary;
|
|
115
|
+
getCurrentBuffer().clear();
|
|
116
|
+
currentBufferStartTime_ = timestamp;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
getCurrentBuffer().push_back({element, timestamp});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
void enqueueElement(T &&element, HighResTimeStamp timestamp)
|
|
124
|
+
{
|
|
125
|
+
if (windowSize_) {
|
|
126
|
+
if (currentBufferStartTime_ == kCurrentBufferStartTimeUninitialized) {
|
|
127
|
+
currentBufferStartTime_ = timestamp;
|
|
128
|
+
} else if (timestamp > currentBufferStartTime_ + *windowSize_) {
|
|
129
|
+
// We moved past the current buffer. We need to switch the other buffer as current.
|
|
130
|
+
currentBufferIndex_ =
|
|
131
|
+
currentBufferIndex_ == BufferIndex::Primary ? BufferIndex::Alternative : BufferIndex::Primary;
|
|
132
|
+
getCurrentBuffer().clear();
|
|
133
|
+
currentBufferStartTime_ = timestamp;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
getCurrentBuffer().push_back({std::move(element), timestamp});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
bool isInsideTimeWindow(const TimestampedElement &element, HighResTimeStamp windowRightBoundary) const
|
|
141
|
+
{
|
|
142
|
+
if (!windowSize_) {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return element.timestamp >= windowRightBoundary - *windowSize_ && element.timestamp <= windowRightBoundary;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
std::optional<TimestampAccessor> timestampAccessor_;
|
|
150
|
+
std::optional<HighResDuration> windowSize_;
|
|
151
|
+
|
|
152
|
+
std::vector<TimestampedElement> primaryBuffer_;
|
|
153
|
+
std::vector<TimestampedElement> alternativeBuffer_;
|
|
154
|
+
BufferIndex currentBufferIndex_ = BufferIndex::Primary;
|
|
155
|
+
HighResTimeStamp currentBufferStartTime_{kCurrentBufferStartTimeUninitialized};
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
} // namespace facebook::react::jsinspector_modern::tracing
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
|
+
#include <jsinspector-modern/tracing/TracingCategory.h>
|
|
10
11
|
#include <react/timing/primitives.h>
|
|
11
12
|
|
|
12
13
|
#include <folly/dynamic.h>
|
|
@@ -40,7 +41,7 @@ struct TraceEvent {
|
|
|
40
41
|
* A comma separated list of categories for the event, configuring how
|
|
41
42
|
* events are shown in the Trace Viewer UI.
|
|
42
43
|
*/
|
|
43
|
-
|
|
44
|
+
Categories cat;
|
|
44
45
|
|
|
45
46
|
/**
|
|
46
47
|
* The event type. This is a single character which changes depending on the
|