Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/

#include <variant>

#include "HermesRuntimeSamplingProfileSerializer.h"

#include <oscompat/OSCompat.h>

#include <variant>

namespace facebook::react::jsinspector_modern::tracing {

namespace {
Expand Down Expand Up @@ -163,6 +165,10 @@ HermesRuntimeSamplingProfileSerializer::serializeToTracingSamplingProfile(

return RuntimeSamplingProfile{
"Hermes",
// Hermes' Profile should be the source of truth for this,
// but it is safe to reuse the process ID here, since everything runs in
// the same process.
oscompat::getCurrentProcessId(),
std::move(reconciledSamples),
std::make_unique<RawHermesRuntimeProfile>(std::move(hermesProfile))};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ void InstanceAgent::maybeSendPendingConsoleMessages() {

void InstanceAgent::startTracing() {
if (runtimeAgent_) {
runtimeAgent_->registerForTracing();
runtimeAgent_->enableSamplingProfiler();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,6 @@ RuntimeAgent::~RuntimeAgent() {
sessionState_.lastRuntimeAgentExportedState = getExportedState();
}

void RuntimeAgent::registerForTracing() {
targetController_.registerForTracing();
}

void RuntimeAgent::enableSamplingProfiler() {
targetController_.enableSamplingProfiler();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,6 @@ class RuntimeAgent final {
*/
ExportedState getExportedState();

/**
* Registers the corresponding RuntimeTarget for Tracing: might enable some
* capabilities that will be later used in Tracing Profile.
*/
void registerForTracing();

/**
* Start sampling profiler for the corresponding RuntimeTarget.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,6 @@ void RuntimeTargetController::notifyDebuggerSessionDestroyed() {
target_.emitDebuggerSessionDestroyed();
}

void RuntimeTargetController::registerForTracing() {
target_.registerForTracing();
}

void RuntimeTargetController::enableSamplingProfiler() {
target_.enableSamplingProfiler();
}
Expand All @@ -179,12 +175,6 @@ RuntimeTargetController::collectSamplingProfile() {
return target_.collectSamplingProfile();
}

void RuntimeTarget::registerForTracing() {
jsExecutor_([](auto& /*runtime*/) {
tracing::PerformanceTracer::getInstance().reportJavaScriptThread();
});
}

void RuntimeTarget::enableSamplingProfiler() {
delegate_.enableSamplingProfiler();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,6 @@ class RuntimeTargetController {
*/
void notifyDebuggerSessionDestroyed();

/**
* Registers the corresponding RuntimeTarget for Tracing: might enable some
* capabilities that will be later used in Tracing Profile.
*/
void registerForTracing();

/**
* Start sampling profiler for the corresponding RuntimeTarget.
*/
Expand Down Expand Up @@ -208,12 +202,6 @@ class JSINSPECTOR_EXPORT RuntimeTarget
const FrontendChannel& channel,
SessionState& sessionState);

/**
* Registers this Runtime for Tracing: might enable some
* capabilities that will be later used in Tracing Profile.
*/
void registerForTracing();

/**
* Start sampling profiler for a particular JavaScript runtime.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,14 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) {
performanceTracer.collectEvents(
dataCollectedCallback, TRACE_EVENT_CHUNK_SIZE);

tracing::RuntimeSamplingProfileTraceEventSerializer serializer(
performanceTracer,
dataCollectedCallback,
PROFILE_TRACE_EVENT_CHUNK_SIZE);
auto tracingProfile = instanceAgent_->collectTracingProfile();
serializer.serializeAndNotify(
tracing::IdGenerator profileIdGenerator;
tracing::RuntimeSamplingProfileTraceEventSerializer::serializeAndDispatch(
std::move(tracingProfile.runtimeSamplingProfile),
instanceTracingStartTimestamp_);
profileIdGenerator,
instanceTracingStartTimestamp_,
dataCollectedCallback,
PROFILE_TRACE_EVENT_CHUNK_SIZE);

frontendChannel_(cdp::jsonNotification(
"Tracing.tracingComplete",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,21 @@ PerformanceTracer::PerformanceTracer()
: processId_(oscompat::getCurrentProcessId()) {}

bool PerformanceTracer::startTracing() {
{
std::lock_guard lock(mutex_);
if (tracingAtomic_) {
return false;
}
tracingAtomic_ = true;
std::lock_guard lock(mutex_);
if (tracingAtomic_) {
return false;
}
tracingAtomic_ = true;

reportProcess(processId_, "React Native");

{
std::lock_guard lock(mutex_);
if (!tracingAtomic_) {
return false;
}
buffer_.emplace_back(TraceEvent{
.name = "TracingStartedInPage",
.cat = "disabled-by-default-devtools.timeline",
.ph = 'I',
.ts = HighResTimeStamp::now(),
.pid = processId_,
.tid = oscompat::getCurrentThreadId(),
.args = folly::dynamic::object("data", folly::dynamic::object()),
});
}
buffer_.emplace_back(TraceEvent{
.name = "TracingStartedInPage",
.cat = "disabled-by-default-devtools.timeline",
.ph = 'I',
.ts = HighResTimeStamp::now(),
.pid = processId_,
.tid = oscompat::getCurrentThreadId(),
.args = folly::dynamic::object("data", folly::dynamic::object()),
});

return true;
}
Expand Down Expand Up @@ -141,6 +131,15 @@ folly::dynamic PerformanceTracer::collectEvents(uint16_t chunkSize) {
return chunks;
}

std::vector<TraceEvent> PerformanceTracer::collectTraceEvents() {
std::vector<TraceEvent> events;
{
std::lock_guard lock(mutex_);
buffer_.swap(events);
}
return events;
}

void PerformanceTracer::reportMark(
const std::string_view& name,
HighResTimeStamp start,
Expand Down Expand Up @@ -269,66 +268,6 @@ void PerformanceTracer::reportTimeStamp(
});
}

void PerformanceTracer::reportProcess(uint64_t id, const std::string& name) {
if (!tracingAtomic_) {
return;
}

std::lock_guard<std::mutex> lock(mutex_);
if (!tracingAtomic_) {
return;
}

buffer_.emplace_back(TraceEvent{
.name = "process_name",
.cat = "__metadata",
.ph = 'M',
.ts = TRACING_TIME_ORIGIN,
.pid = id,
.tid = 0,
.args = folly::dynamic::object("name", name),
});
}

void PerformanceTracer::reportJavaScriptThread() {
reportThread(oscompat::getCurrentThreadId(), "JavaScript");
}

void PerformanceTracer::reportThread(uint64_t id, const std::string& name) {
if (!tracingAtomic_) {
return;
}

std::lock_guard<std::mutex> lock(mutex_);
if (!tracingAtomic_) {
return;
}

buffer_.emplace_back(TraceEvent{
.name = "thread_name",
.cat = "__metadata",
.ph = 'M',
.ts = TRACING_TIME_ORIGIN,
.pid = processId_,
.tid = id,
.args = folly::dynamic::object("name", name),
});

// This is synthetic Trace Event, which should not be represented on a
// timeline. CDT will filter out threads that only have JavaScript samples and
// no timeline events or user timings. We use this event to avoid that.
// This could happen for non-bridgeless apps, where Performance interface is
// not supported and no spec-compliant Event Loop implementation.
buffer_.emplace_back(TraceEvent{
.name = "ReactNative-ThreadRegistered",
.cat = "disabled-by-default-devtools.timeline",
.ph = 'I',
.ts = TRACING_TIME_ORIGIN,
.pid = processId_,
.tid = id,
});
}

void PerformanceTracer::reportEventLoopTask(
HighResTimeStamp start,
HighResTimeStamp end) {
Expand Down Expand Up @@ -375,46 +314,49 @@ void PerformanceTracer::reportEventLoopMicrotasks(
});
}

folly::dynamic PerformanceTracer::getSerializedRuntimeProfileTraceEvent(
uint64_t threadId,
uint16_t profileId,
/* static */ TraceEvent PerformanceTracer::constructRuntimeProfileTraceEvent(
RuntimeProfileId profileId,
ProcessId processId,
ThreadId threadId,
HighResTimeStamp profileTimestamp) {
// CDT prioritizes event timestamp over startTime metadata field.
// https://fburl.com/lo764pf4
return TraceEventSerializer::serialize(TraceEvent{
return TraceEvent{
.id = profileId,
.name = "Profile",
.cat = "disabled-by-default-v8.cpu_profiler",
.ph = 'P',
.ts = profileTimestamp,
.pid = processId_,
.pid = processId,
.tid = threadId,
.args = folly::dynamic::object(
"data",
folly::dynamic::object(
"startTime",
highResTimeStampToTracingClockTimeStamp(profileTimestamp))),
});
};
}

folly::dynamic PerformanceTracer::getSerializedRuntimeProfileChunkTraceEvent(
uint16_t profileId,
uint64_t threadId,
/* static */ TraceEvent
PerformanceTracer::constructRuntimeProfileChunkTraceEvent(
RuntimeProfileId profileId,
ProcessId processId,
ProcessId threadId,
HighResTimeStamp chunkTimestamp,
tracing::TraceEventProfileChunk&& traceEventProfileChunk) {
return TraceEventSerializer::serialize(TraceEvent{
TraceEventProfileChunk&& traceEventProfileChunk) {
return TraceEvent{
.id = profileId,
.name = "ProfileChunk",
.cat = "disabled-by-default-v8.cpu_profiler",
.ph = 'P',
.ts = chunkTimestamp,
.pid = processId_,
.pid = processId,
.tid = threadId,
.args = folly::dynamic::object(
"data",
TraceEventSerializer::serializeProfileChunk(
std::move(traceEventProfileChunk))),
});
};
}

} // namespace facebook::react::jsinspector_modern::tracing
Loading
Loading