Skip to content

Commit c9bee00

Browse files
hoxyqfacebook-github-bot
authored andcommitted
Record Microtasks step (#50586)
Summary: Pull Request resolved: #50586 # Changelog: [Internal] We are going to record microtasks phase of the Event Loop. RAII reporter that was added in D69399955 will be updated to support phase as a parameter. There is one downside of the current implementation. Every Event Loop task will have a corresponding "Run Microtasks" block displayed, even if the microtasks queue was empty. There is no API in `jsi` that would allow us to get the size of the queue. If we had that, we could emit this event only when there is something in a microtasks queue. The good this is that these frames usually have duration of 1-2 microseconds, so they are not visible, until user fully zooms in. Reviewed By: rubennorte Differential Revision: D72649816 fbshipit-source-id: d597f5b75aaf0975b14f61d2aa28b9c8bc34f4d5
1 parent 5bf54bc commit c9bee00

File tree

5 files changed

+71
-21
lines changed

5 files changed

+71
-21
lines changed

packages/react-native/ReactCommon/jsinspector-modern/tracing/EventLoopTaskReporter.cpp renamed to packages/react-native/ReactCommon/jsinspector-modern/tracing/EventLoopReporter.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
#include "EventLoopTaskReporter.h"
8+
#include "EventLoopReporter.h"
99

1010
#if defined(REACT_NATIVE_DEBUGGER_ENABLED)
1111
#include "PerformanceTracer.h"
@@ -25,24 +25,37 @@ inline uint64_t formatTimePointToUnixTimestamp(
2525

2626
} // namespace
2727

28-
EventLoopTaskReporter::EventLoopTaskReporter()
29-
: startTimestamp_(std::chrono::steady_clock::now()) {}
28+
EventLoopReporter::EventLoopReporter(EventLoopPhase phase)
29+
: startTimestamp_(std::chrono::steady_clock::now()), phase_(phase) {}
3030

31-
EventLoopTaskReporter::~EventLoopTaskReporter() {
31+
EventLoopReporter::~EventLoopReporter() {
3232
PerformanceTracer& performanceTracer = PerformanceTracer::getInstance();
3333
if (performanceTracer.isTracing()) {
3434
auto end = std::chrono::steady_clock::now();
35-
performanceTracer.reportEventLoopTask(
36-
formatTimePointToUnixTimestamp(startTimestamp_),
37-
formatTimePointToUnixTimestamp(end));
35+
switch (phase_) {
36+
case EventLoopPhase::Task:
37+
performanceTracer.reportEventLoopTask(
38+
formatTimePointToUnixTimestamp(startTimestamp_),
39+
formatTimePointToUnixTimestamp(end));
40+
break;
41+
42+
case EventLoopPhase::Microtasks:
43+
performanceTracer.reportEventLoopMicrotasks(
44+
formatTimePointToUnixTimestamp(startTimestamp_),
45+
formatTimePointToUnixTimestamp(end));
46+
break;
47+
48+
default:
49+
break;
50+
}
3851
}
3952
}
4053

4154
#else
4255

43-
EventLoopTaskReporter::EventLoopTaskReporter() {}
56+
EventLoopReporter::EventLoopReporter(EventLoopPhase phase) {}
4457

45-
EventLoopTaskReporter::~EventLoopTaskReporter() {}
58+
EventLoopReporter::~EventLoopReporter() {}
4659

4760
#endif
4861

packages/react-native/ReactCommon/jsinspector-modern/tracing/EventLoopTaskReporter.h renamed to packages/react-native/ReactCommon/jsinspector-modern/tracing/EventLoopReporter.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,26 @@
1111

1212
namespace facebook::react::jsinspector_modern::tracing {
1313

14-
struct EventLoopTaskReporter {
14+
enum class EventLoopPhase {
15+
Task,
16+
Microtasks,
17+
};
18+
19+
struct EventLoopReporter {
1520
public:
16-
EventLoopTaskReporter();
21+
explicit EventLoopReporter(EventLoopPhase phase);
1722

18-
EventLoopTaskReporter(const EventLoopTaskReporter&) = delete;
19-
EventLoopTaskReporter(EventLoopTaskReporter&&) = delete;
20-
EventLoopTaskReporter& operator=(const EventLoopTaskReporter&) = delete;
21-
EventLoopTaskReporter& operator=(EventLoopTaskReporter&&) = delete;
23+
EventLoopReporter(const EventLoopReporter&) = delete;
24+
EventLoopReporter(EventLoopReporter&&) = delete;
25+
EventLoopReporter& operator=(const EventLoopReporter&) = delete;
26+
EventLoopReporter& operator=(EventLoopReporter&&) = delete;
2227

23-
~EventLoopTaskReporter();
28+
~EventLoopReporter();
2429

2530
private:
2631
#if defined(REACT_NATIVE_DEBUGGER_ENABLED)
2732
std::chrono::steady_clock::time_point startTimestamp_;
33+
EventLoopPhase phase_;
2834
#endif
2935
};
3036

packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,29 @@ void PerformanceTracer::reportEventLoopTask(uint64_t start, uint64_t end) {
264264
});
265265
}
266266

267+
void PerformanceTracer::reportEventLoopMicrotasks(
268+
uint64_t start,
269+
uint64_t end) {
270+
if (!tracing_) {
271+
return;
272+
}
273+
274+
std::lock_guard lock(mutex_);
275+
if (!tracing_) {
276+
return;
277+
}
278+
279+
buffer_.push_back(TraceEvent{
280+
.name = "RunMicrotasks",
281+
.cat = "v8.execute",
282+
.ph = 'X',
283+
.ts = start,
284+
.pid = oscompat::getCurrentProcessId(),
285+
.tid = oscompat::getCurrentThreadId(),
286+
.dur = end - start,
287+
});
288+
}
289+
267290
folly::dynamic PerformanceTracer::getSerializedRuntimeProfileTraceEvent(
268291
uint64_t threadId,
269292
uint16_t profileId,

packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ class PerformanceTracer {
101101
*/
102102
void reportEventLoopTask(uint64_t start, uint64_t end);
103103

104+
/**
105+
* Record Microtasks phase of the Event Loop tick. Will be represented as a
106+
* "Run Microtasks" block under a task.
107+
*/
108+
void reportEventLoopMicrotasks(uint64_t start, uint64_t end);
109+
104110
/**
105111
* Create and serialize Profile Trace Event.
106112
* \return serialized Trace Event that represents a Profile for CDT.

packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include "SchedulerPriorityUtils.h"
1010

1111
#include <cxxreact/TraceSection.h>
12-
#include <jsinspector-modern/tracing/EventLoopTaskReporter.h>
12+
#include <jsinspector-modern/tracing/EventLoopReporter.h>
1313
#include <react/featureflags/ReactNativeFeatureFlags.h>
1414
#include <react/renderer/consistency/ScopedShadowTreeRevisionLock.h>
1515
#include <react/timing/primitives.h>
@@ -307,8 +307,8 @@ void RuntimeScheduler_Modern::runEventLoopTick(
307307
Task& task,
308308
RuntimeSchedulerTimePoint taskStartTime) {
309309
TraceSection s("RuntimeScheduler::runEventLoopTick");
310-
[[maybe_unused]] jsinspector_modern::tracing::EventLoopTaskReporter
311-
performanceReporter;
310+
jsinspector_modern::tracing::EventLoopReporter performanceReporter(
311+
jsinspector_modern::tracing::EventLoopPhase::Task);
312312

313313
ScopedShadowTreeRevisionLock revisionLock(
314314
shadowTreeRevisionConsistencyManager_);
@@ -395,12 +395,14 @@ void RuntimeScheduler_Modern::executeTask(
395395
*/
396396
void RuntimeScheduler_Modern::performMicrotaskCheckpoint(
397397
jsi::Runtime& runtime) {
398-
TraceSection s("RuntimeScheduler::performMicrotaskCheckpoint");
399-
400398
if (performingMicrotaskCheckpoint_) {
401399
return;
402400
}
403401

402+
TraceSection s("RuntimeScheduler::performMicrotaskCheckpoint");
403+
jsinspector_modern::tracing::EventLoopReporter performanceReporter(
404+
jsinspector_modern::tracing::EventLoopPhase::Microtasks);
405+
404406
performingMicrotaskCheckpoint_ = true;
405407
OnScopeExit restoreFlag([&]() { performingMicrotaskCheckpoint_ = false; });
406408

0 commit comments

Comments
 (0)