Skip to content

Commit 98d1a6e

Browse files
hoxyfacebook-github-bot
authored andcommitted
Scaffold support for Tracing by jsinspector (facebook#48836)
Summary: Pull Request resolved: facebook#48836 # Changelog: [Internal] When `Tracing.start` CDP method is received, here is what happens next: - `TracingAgent`, which intercepts the event will propagate this status to `Instance` by calling `startTracing()` on `InstanceAgent`. - `InstanceAgent` will propagate it to `Runtime` entities. The only difference, there is no concept of tracing for Runtime, it will only have an API for starting sampling profiler. When `Tracing.end` CDP method is received, it is propagated in the same order. There is also `collect*()` methods for collecting profiles. This has multiple benefits: - We can control when `Runtime` or `Instance` are recreated and can ask them to start recording trace profiles right away. This may be required when we would add support for Reload and Profile from Performance panel. - We might leverage this setup in the future, once we add instrumentation for Network panel. `InstanceAgent` will get notified when tracing started and will correspondingly notify other part of the infrastructure that will be responsible for recording network calls. - We remain being fully agnostic to the actual `Runtime`, see corresponding `RuntimeTargetDelegate` for `V8`. We don't have the capacity for implementing and maintaining sampling profiler capabilities for it, but this approach unblocks it from technical perspective, if someone would want to invest into this. `InstanceProfile` is a superset of `RuntimeSamplingProfile`. In the future, `InstanceProfile` may also include things like `NetworkProfile`, or similar stuff. The definition for `RuntimeSamplingProfile` will be added in D68414421 and relies on the availability of new API for sampling profiler in Hermes. Differential Revision: D68327630 Reviewed By: huntie
1 parent 987965a commit 98d1a6e

21 files changed

+302
-7
lines changed

packages/react-native/React/CoreModules/React-CoreModules.podspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Pod::Spec.new do |s|
7070
s.dependency 'React-RCTBlob'
7171
s.dependency "SocketRocket", socket_rocket_version
7272
add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern')
73+
add_dependency(s, "React-jsinspectortracing", :framework_name => 'jsinspector_moderntracing')
7374

7475
add_dependency(s, "React-RCTFBReactNativeSpec")
7576
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])

packages/react-native/ReactCommon/cxxreact/React-cxxreact.podspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Pod::Spec.new do |s|
4848
s.dependency "RCT-Folly", folly_version
4949
s.dependency "glog"
5050
add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern')
51+
add_dependency(s, "React-jsinspectortracing", :framework_name => 'jsinspector_moderntracing')
5152
s.dependency "React-callinvoker", version
5253
s.dependency "React-runtimeexecutor", version
5354
s.dependency "React-perflogger", version

packages/react-native/ReactCommon/hermes/React-hermes.podspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Pod::Spec.new do |s|
4444
s.dependency "React-cxxreact", version
4545
s.dependency "React-jsiexecutor", version
4646
add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern')
47+
add_dependency(s, "React-jsinspectortracing", :framework_name => 'jsinspector_moderntracing')
4748
s.dependency "React-perflogger", version
4849
s.dependency "RCT-Folly", folly_version
4950
s.dependency "DoubleConversion"

packages/react-native/ReactCommon/hermes/inspector-modern/chrome/HermesRuntimeTargetDelegate.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ using namespace facebook::hermes;
2828
namespace facebook::react::jsinspector_modern {
2929

3030
#ifdef HERMES_ENABLE_DEBUGGER
31+
namespace {
32+
33+
const uint16_t HERMES_SAMPLING_FREQUENCY_HZ = 1000;
34+
35+
} // namespace
36+
3137
class HermesRuntimeTargetDelegate::Impl final : public RuntimeTargetDelegate {
3238
using HermesStackTrace = debugger::StackTrace;
3339

@@ -167,6 +173,18 @@ class HermesRuntimeTargetDelegate::Impl final : public RuntimeTargetDelegate {
167173
runtime_->getDebugger().captureStackTrace());
168174
}
169175

176+
void enableSamplingProfiler() override {
177+
runtime_->enableSamplingProfiler(HERMES_SAMPLING_FREQUENCY_HZ);
178+
}
179+
180+
void disableSamplingProfiler() override {
181+
runtime_->disableSamplingProfiler();
182+
}
183+
184+
tracing::RuntimeSamplingProfile collectSamplingProfile() override {
185+
return tracing::RuntimeSamplingProfile{};
186+
}
187+
170188
private:
171189
HermesRuntimeTargetDelegate& delegate_;
172190
std::shared_ptr<HermesRuntime> runtime_;
@@ -228,6 +246,19 @@ std::unique_ptr<StackTrace> HermesRuntimeTargetDelegate::captureStackTrace(
228246
return impl_->captureStackTrace(runtime, framesToSkip);
229247
}
230248

249+
void HermesRuntimeTargetDelegate::enableSamplingProfiler() {
250+
impl_->enableSamplingProfiler();
251+
}
252+
253+
void HermesRuntimeTargetDelegate::disableSamplingProfiler() {
254+
impl_->disableSamplingProfiler();
255+
}
256+
257+
tracing::RuntimeSamplingProfile
258+
HermesRuntimeTargetDelegate::collectSamplingProfile() {
259+
return impl_->collectSamplingProfile();
260+
}
261+
231262
#ifdef HERMES_ENABLE_DEBUGGER
232263
CDPDebugAPI& HermesRuntimeTargetDelegate::getCDPDebugAPI() {
233264
return impl_->getCDPDebugAPI();

packages/react-native/ReactCommon/hermes/inspector-modern/chrome/HermesRuntimeTargetDelegate.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ class HermesRuntimeTargetDelegate : public RuntimeTargetDelegate {
5454
jsi::Runtime& runtime,
5555
size_t framesToSkip) override;
5656

57+
void enableSamplingProfiler() override;
58+
59+
void disableSamplingProfiler() override;
60+
61+
tracing::RuntimeSamplingProfile collectSamplingProfile() override;
62+
5763
private:
5864
// We use the private implementation idiom to ensure this class has the same
5965
// layout regardless of whether HERMES_ENABLE_DEBUGGER is defined. The net

packages/react-native/ReactCommon/jsiexecutor/React-jsiexecutor.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Pod::Spec.new do |s|
4646
s.dependency "fmt", "11.0.2"
4747
s.dependency "glog"
4848
add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern')
49-
49+
add_dependency(s, "React-jsinspectortracing", :framework_name => 'jsinspector_moderntracing')
5050
if ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == "1"
5151
s.dependency 'hermes-engine'
5252
end

packages/react-native/ReactCommon/jsinspector-modern/FallbackRuntimeTargetDelegate.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,18 @@ std::unique_ptr<StackTrace> FallbackRuntimeTargetDelegate::captureStackTrace(
4444
return std::make_unique<StackTrace>();
4545
}
4646

47+
void FallbackRuntimeTargetDelegate::enableSamplingProfiler() {
48+
// no-op
49+
};
50+
51+
void FallbackRuntimeTargetDelegate::disableSamplingProfiler() {
52+
// no-op
53+
};
54+
55+
tracing::RuntimeSamplingProfile
56+
FallbackRuntimeTargetDelegate::collectSamplingProfile() {
57+
throw std::logic_error(
58+
"Sampling Profiler capabilities are not supported for Runtime fallback");
59+
}
60+
4761
} // namespace facebook::react::jsinspector_modern

packages/react-native/ReactCommon/jsinspector-modern/FallbackRuntimeTargetDelegate.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ class FallbackRuntimeTargetDelegate : public RuntimeTargetDelegate {
4040
jsi::Runtime& runtime,
4141
size_t framesToSkip) override;
4242

43+
void enableSamplingProfiler() override;
44+
45+
void disableSamplingProfiler() override;
46+
47+
tracing::RuntimeSamplingProfile collectSamplingProfile() override;
48+
4349
private:
4450
std::string engineDescription_;
4551
};

packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,11 @@ void HostAgent::sendInfoLogEntry(
237237

238238
void HostAgent::setCurrentInstanceAgent(
239239
std::shared_ptr<InstanceAgent> instanceAgent) {
240+
tracingAgent_.setCurrentInstanceAgent(instanceAgent);
241+
240242
auto previousInstanceAgent = std::move(instanceAgent_);
241243
instanceAgent_ = std::move(instanceAgent);
244+
242245
if (!sessionState_.isRuntimeDomainEnabled) {
243246
return;
244247
}

packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,23 @@ void InstanceAgent::maybeSendPendingConsoleMessages() {
152152
}
153153
}
154154

155+
void InstanceAgent::startTracing() {
156+
if (runtimeAgent_) {
157+
runtimeAgent_->enableSamplingProfiler();
158+
}
159+
}
160+
161+
void InstanceAgent::stopTracing() {
162+
if (runtimeAgent_) {
163+
runtimeAgent_->disableSamplingProfiler();
164+
}
165+
}
166+
167+
tracing::InstanceTracingProfile InstanceAgent::collectTracingProfile() {
168+
tracing::RuntimeSamplingProfile runtimeSamplingProfile =
169+
runtimeAgent_->collectSamplingProfile();
170+
171+
return tracing::InstanceTracingProfile{runtimeSamplingProfile};
172+
}
173+
155174
} // namespace facebook::react::jsinspector_modern

0 commit comments

Comments
 (0)