mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Improve profiling information for timers (#45091)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/45091 Changelog: [internal] We're currently logging when we execute timers in Systrace/Perfetto, but we have no information about them whatsoever. This adds some additional information: * What kind of timer it is * It's ID * And most importantly, when it was created (including the ID as well). This allows us to know where was a specific timer scheduled and with what API. Reviewed By: bgirard Differential Revision: D58832112 fbshipit-source-id: 1bc11759b6c8296acf63ff3533ca1dc3428360a7
This commit is contained in:
committed by
Facebook GitHub Bot
parent
fdf0183831
commit
a8a76f9bfa
@@ -13,6 +13,21 @@
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
namespace {
|
||||
inline const char* getTimerSourceName(TimerSource source) {
|
||||
switch (source) {
|
||||
case TimerSource::Unknown:
|
||||
return "unknown";
|
||||
case TimerSource::SetTimeout:
|
||||
return "setTimeout";
|
||||
case TimerSource::SetInterval:
|
||||
return "setInterval";
|
||||
case TimerSource::RequestAnimationFrame:
|
||||
return "requestAnimationFrame";
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TimerManager::TimerManager(
|
||||
std::unique_ptr<PlatformTimerRegistry> platformTimerRegistry) noexcept
|
||||
: platformTimerRegistry_(std::move(platformTimerRegistry)) {}
|
||||
@@ -60,14 +75,28 @@ void TimerManager::callReactNativeMicrotasks(jsi::Runtime& runtime) {
|
||||
TimerHandle TimerManager::createTimer(
|
||||
jsi::Function&& callback,
|
||||
std::vector<jsi::Value>&& args,
|
||||
double delay) {
|
||||
double delay,
|
||||
TimerSource source) {
|
||||
// Get the id for the callback.
|
||||
TimerHandle timerID = timerIndex_++;
|
||||
|
||||
SystraceSection s(
|
||||
"TimerManager::createTimer",
|
||||
"id",
|
||||
timerID,
|
||||
"type",
|
||||
getTimerSourceName(source),
|
||||
"delay",
|
||||
delay);
|
||||
|
||||
timers_.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(timerID),
|
||||
std::forward_as_tuple(
|
||||
std::move(callback), std::move(args), /* repeat */ false));
|
||||
std::move(callback),
|
||||
std::move(args),
|
||||
/* repeat */ false,
|
||||
source));
|
||||
|
||||
platformTimerRegistry_->createTimer(timerID, delay);
|
||||
|
||||
@@ -77,14 +106,25 @@ TimerHandle TimerManager::createTimer(
|
||||
TimerHandle TimerManager::createRecurringTimer(
|
||||
jsi::Function&& callback,
|
||||
std::vector<jsi::Value>&& args,
|
||||
double delay) {
|
||||
double delay,
|
||||
TimerSource source) {
|
||||
// Get the id for the callback.
|
||||
TimerHandle timerID = timerIndex_++;
|
||||
|
||||
SystraceSection s(
|
||||
"TimerManager::createRecurringTimer",
|
||||
"id",
|
||||
timerID,
|
||||
"type",
|
||||
getTimerSourceName(source),
|
||||
"delay",
|
||||
delay);
|
||||
|
||||
timers_.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(timerID),
|
||||
std::forward_as_tuple(
|
||||
std::move(callback), std::move(args), /* repeat */ true));
|
||||
std::move(callback), std::move(args), /* repeat */ true, source));
|
||||
|
||||
platformTimerRegistry_->createRecurringTimer(timerID, delay);
|
||||
|
||||
@@ -131,11 +171,20 @@ void TimerManager::deleteRecurringTimer(
|
||||
|
||||
void TimerManager::callTimer(TimerHandle timerHandle) {
|
||||
runtimeExecutor_([this, timerHandle](jsi::Runtime& runtime) {
|
||||
SystraceSection s("TimerManager::callTimer");
|
||||
auto it = timers_.find(timerHandle);
|
||||
if (it != timers_.end()) {
|
||||
bool repeats = it->second.repeat;
|
||||
it->second.invoke(runtime);
|
||||
auto& timerCallback = it->second;
|
||||
bool repeats = timerCallback.repeat;
|
||||
|
||||
{
|
||||
SystraceSection s(
|
||||
"TimerManager::callTimer",
|
||||
"id",
|
||||
timerHandle,
|
||||
"type",
|
||||
getTimerSourceName(timerCallback.source));
|
||||
timerCallback.invoke(runtime);
|
||||
}
|
||||
|
||||
if (!repeats) {
|
||||
// Invoking a timer has the potential to delete it. Do not re-use the
|
||||
@@ -246,7 +295,11 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
|
||||
moreArgs.emplace_back(rt, args[extraArgNum]);
|
||||
}
|
||||
|
||||
return createTimer(std::move(callback), std::move(moreArgs), delay);
|
||||
return createTimer(
|
||||
std::move(callback),
|
||||
std::move(moreArgs),
|
||||
delay,
|
||||
TimerSource::SetTimeout);
|
||||
}));
|
||||
|
||||
runtime.global().setProperty(
|
||||
@@ -301,7 +354,10 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
|
||||
}
|
||||
|
||||
return createRecurringTimer(
|
||||
std::move(callback), std::move(moreArgs), delay);
|
||||
std::move(callback),
|
||||
std::move(moreArgs),
|
||||
delay,
|
||||
TimerSource::SetInterval);
|
||||
}));
|
||||
|
||||
runtime.global().setProperty(
|
||||
@@ -370,7 +426,8 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
|
||||
return createTimer(
|
||||
std::move(callback),
|
||||
std::vector<jsi::Value>(),
|
||||
/* delay */ 0);
|
||||
/* delay */ 0,
|
||||
TimerSource::RequestAnimationFrame);
|
||||
}));
|
||||
|
||||
runtime.global().setProperty(
|
||||
|
||||
@@ -18,6 +18,13 @@ namespace facebook::react {
|
||||
|
||||
using TimerHandle = int;
|
||||
|
||||
enum class TimerSource {
|
||||
Unknown,
|
||||
SetTimeout,
|
||||
SetInterval,
|
||||
RequestAnimationFrame
|
||||
};
|
||||
|
||||
/*
|
||||
* Wraps a jsi::Function to make it copyable so we can pass it into a lambda.
|
||||
*/
|
||||
@@ -25,10 +32,12 @@ struct TimerCallback {
|
||||
TimerCallback(
|
||||
jsi::Function callback,
|
||||
std::vector<jsi::Value> args,
|
||||
bool repeat)
|
||||
bool repeat,
|
||||
TimerSource source = TimerSource::Unknown)
|
||||
: callback_(std::move(callback)),
|
||||
args_(std::move(args)),
|
||||
repeat(repeat) {}
|
||||
repeat(repeat),
|
||||
source(source) {}
|
||||
|
||||
void invoke(jsi::Runtime& runtime) {
|
||||
callback_.call(runtime, args_.data(), args_.size());
|
||||
@@ -37,6 +46,7 @@ struct TimerCallback {
|
||||
jsi::Function callback_;
|
||||
const std::vector<jsi::Value> args_;
|
||||
bool repeat;
|
||||
TimerSource source;
|
||||
};
|
||||
|
||||
class TimerManager {
|
||||
@@ -62,14 +72,16 @@ class TimerManager {
|
||||
TimerHandle createTimer(
|
||||
jsi::Function&& callback,
|
||||
std::vector<jsi::Value>&& args,
|
||||
double delay);
|
||||
double delay,
|
||||
TimerSource source = TimerSource::Unknown);
|
||||
|
||||
void deleteTimer(jsi::Runtime& runtime, TimerHandle handle);
|
||||
|
||||
TimerHandle createRecurringTimer(
|
||||
jsi::Function&& callback,
|
||||
std::vector<jsi::Value>&& args,
|
||||
double delay);
|
||||
double delay,
|
||||
TimerSource source = TimerSource::Unknown);
|
||||
|
||||
void deleteRecurringTimer(jsi::Runtime& runtime, TimerHandle handle);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user