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 @@ -179,7 +179,7 @@ RuntimeTargetController::collectSamplingProfile() {

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) {
}

bool correctlyStartedPerformanceTracer =
PerformanceTracer::getInstance().startTracing();
tracing::PerformanceTracer::getInstance().startTracing();

if (!correctlyStartedPerformanceTracer) {
frontendChannel_(cdp::jsonError(
Expand All @@ -56,7 +56,7 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) {
}

instanceAgent_->startTracing();
instanceTracingStartTimestamp_ = std::chrono::steady_clock::now();
instanceTracingStartTimestamp_ = HighResTimeStamp::now();
frontendChannel_(cdp::jsonResult(req.id));

return true;
Expand All @@ -73,7 +73,8 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) {

instanceAgent_->stopTracing();

PerformanceTracer& performanceTracer = PerformanceTracer::getInstance();
tracing::PerformanceTracer& performanceTracer =
tracing::PerformanceTracer::getInstance();
bool correctlyStopped = performanceTracer.stopTracing();
if (!correctlyStopped) {
frontendChannel_(cdp::jsonError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "InstanceAgent.h"

#include <jsinspector-modern/cdp/CdpJson.h>
#include <jsinspector-modern/tracing/Timing.h>
#include <react/timing/primitives.h>

namespace facebook::react::jsinspector_modern {

Expand Down Expand Up @@ -54,9 +56,10 @@ class TracingAgent {

/**
* Timestamp of when we started tracing of an Instance, will be used as a
* a start of JavaScript samples recording.
* a start of JavaScript samples recording and as a time origin for the events
* in this trace.
*/
std::chrono::steady_clock::time_point instanceTracingStartTimestamp_;
HighResTimeStamp instanceTracingStartTimestamp_;
};

} // namespace facebook::react::jsinspector_modern
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ target_include_directories(jsinspector_tracing PUBLIC ${REACT_COMMON_DIR})
target_link_libraries(jsinspector_tracing
folly_runtime
oscompat
react_timing
)
target_compile_reactnative_options(jsinspector_tracing PRIVATE)
target_compile_options(jsinspector_tracing PRIVATE -Wpedantic)
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,21 @@
namespace facebook::react::jsinspector_modern::tracing {

#if defined(REACT_NATIVE_DEBUGGER_ENABLED)
namespace {

inline uint64_t formatTimePointToUnixTimestamp(
std::chrono::steady_clock::time_point timestamp) {
return std::chrono::duration_cast<std::chrono::microseconds>(
timestamp.time_since_epoch())
.count();
}

} // namespace

EventLoopReporter::EventLoopReporter(EventLoopPhase phase)
: startTimestamp_(std::chrono::steady_clock::now()), phase_(phase) {}
: startTimestamp_(HighResTimeStamp::now()), phase_(phase) {}

EventLoopReporter::~EventLoopReporter() {
PerformanceTracer& performanceTracer = PerformanceTracer::getInstance();
if (performanceTracer.isTracing()) {
auto end = std::chrono::steady_clock::now();
auto end = HighResTimeStamp::now();
switch (phase_) {
case EventLoopPhase::Task:
performanceTracer.reportEventLoopTask(
formatTimePointToUnixTimestamp(startTimestamp_),
formatTimePointToUnixTimestamp(end));
performanceTracer.reportEventLoopTask(startTimestamp_, end);
break;

case EventLoopPhase::Microtasks:
performanceTracer.reportEventLoopMicrotasks(
formatTimePointToUnixTimestamp(startTimestamp_),
formatTimePointToUnixTimestamp(end));
performanceTracer.reportEventLoopMicrotasks(startTimestamp_, end);
break;

default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

#pragma once

#include <chrono>
#if defined(REACT_NATIVE_DEBUGGER_ENABLED)
#include <react/timing/primitives.h>
#endif

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

Expand All @@ -29,7 +31,7 @@ struct EventLoopReporter {

private:
#if defined(REACT_NATIVE_DEBUGGER_ENABLED)
std::chrono::steady_clock::time_point startTimestamp_;
HighResTimeStamp startTimestamp_;
EventLoopPhase phase_;
#endif
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#include "PerformanceTracer.h"
#include "Timing.h"

#include <oscompat/OSCompat.h>

Expand All @@ -14,17 +15,7 @@
#include <array>
#include <mutex>

namespace facebook::react::jsinspector_modern {

namespace {

uint64_t getUnixTimestampOfNow() {
return std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count();
}

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

PerformanceTracer& PerformanceTracer::getInstance() {
static PerformanceTracer tracer;
Expand Down Expand Up @@ -52,7 +43,7 @@ bool PerformanceTracer::startTracing() {
.name = "TracingStartedInPage",
.cat = "disabled-by-default-devtools.timeline",
.ph = 'I',
.ts = getUnixTimestampOfNow(),
.ts = HighResTimeStamp::now(),
.pid = processId_,
.tid = oscompat::getCurrentThreadId(),
.args = folly::dynamic::object("data", folly::dynamic::object()),
Expand All @@ -78,7 +69,7 @@ bool PerformanceTracer::stopTracing() {
.name = "ReactNative-TracingStopped",
.cat = "disabled-by-default-devtools.timeline",
.ph = 'I',
.ts = getUnixTimestampOfNow(),
.ts = HighResTimeStamp::now(),
.pid = processId_,
.tid = oscompat::getCurrentThreadId(),
});
Expand Down Expand Up @@ -117,7 +108,7 @@ void PerformanceTracer::collectEvents(

void PerformanceTracer::reportMark(
const std::string_view& name,
uint64_t start) {
HighResTimeStamp start) {
if (!tracing_) {
return;
}
Expand All @@ -139,8 +130,8 @@ void PerformanceTracer::reportMark(

void PerformanceTracer::reportMeasure(
const std::string_view& name,
uint64_t start,
uint64_t duration,
HighResTimeStamp start,
HighResDuration duration,
const std::optional<DevToolsTrackEntryPayload>& trackMetadata) {
if (!tracing_) {
return;
Expand Down Expand Up @@ -197,7 +188,7 @@ void PerformanceTracer::reportProcess(uint64_t id, const std::string& name) {
.name = "process_name",
.cat = "__metadata",
.ph = 'M',
.ts = 0,
.ts = TRACING_TIME_ORIGIN,
.pid = id,
.tid = 0,
.args = folly::dynamic::object("name", name),
Expand All @@ -222,7 +213,7 @@ void PerformanceTracer::reportThread(uint64_t id, const std::string& name) {
.name = "thread_name",
.cat = "__metadata",
.ph = 'M',
.ts = 0,
.ts = TRACING_TIME_ORIGIN,
.pid = processId_,
.tid = id,
.args = folly::dynamic::object("name", name),
Expand All @@ -237,13 +228,15 @@ void PerformanceTracer::reportThread(uint64_t id, const std::string& name) {
.name = "ReactNative-ThreadRegistered",
.cat = "disabled-by-default-devtools.timeline",
.ph = 'I',
.ts = 0,
.ts = TRACING_TIME_ORIGIN,
.pid = processId_,
.tid = id,
});
}

void PerformanceTracer::reportEventLoopTask(uint64_t start, uint64_t end) {
void PerformanceTracer::reportEventLoopTask(
HighResTimeStamp start,
HighResTimeStamp end) {
if (!tracing_) {
return;
}
Expand All @@ -265,8 +258,8 @@ void PerformanceTracer::reportEventLoopTask(uint64_t start, uint64_t end) {
}

void PerformanceTracer::reportEventLoopMicrotasks(
uint64_t start,
uint64_t end) {
HighResTimeStamp start,
HighResTimeStamp end) {
if (!tracing_) {
return;
}
Expand All @@ -290,33 +283,36 @@ void PerformanceTracer::reportEventLoopMicrotasks(
folly::dynamic PerformanceTracer::getSerializedRuntimeProfileTraceEvent(
uint64_t threadId,
uint16_t profileId,
uint64_t eventUnixTimestamp) {
HighResTimeStamp profileTimestamp) {
// CDT prioritizes event timestamp over startTime metadata field.
// https://fburl.com/lo764pf4
return serializeTraceEvent(TraceEvent{
.id = profileId,
.name = "Profile",
.cat = "disabled-by-default-v8.cpu_profiler",
.ph = 'P',
.ts = eventUnixTimestamp,
.ts = profileTimestamp,
.pid = processId_,
.tid = threadId,
.args = folly::dynamic::object(
"data", folly ::dynamic::object("startTime", eventUnixTimestamp)),
"data",
folly ::dynamic::object(
"startTime",
highResTimeStampToTracingClockTimeStamp(profileTimestamp))),
});
}

folly::dynamic PerformanceTracer::getSerializedRuntimeProfileChunkTraceEvent(
uint16_t profileId,
uint64_t threadId,
uint64_t eventUnixTimestamp,
HighResTimeStamp chunkTimestamp,
const tracing::TraceEventProfileChunk& traceEventProfileChunk) {
return serializeTraceEvent(TraceEvent{
.id = profileId,
.name = "ProfileChunk",
.cat = "disabled-by-default-v8.cpu_profiler",
.ph = 'P',
.ts = eventUnixTimestamp,
.ts = chunkTimestamp,
.pid = processId_,
.tid = threadId,
.args =
Expand All @@ -336,15 +332,15 @@ folly::dynamic PerformanceTracer::serializeTraceEvent(
result["name"] = event.name;
result["cat"] = event.cat;
result["ph"] = std::string(1, event.ph);
result["ts"] = event.ts;
result["ts"] = highResTimeStampToTracingClockTimeStamp(event.ts);
result["pid"] = event.pid;
result["tid"] = event.tid;
result["args"] = event.args;
if (event.dur.has_value()) {
result["dur"] = event.dur.value();
result["dur"] = highResDurationToTracingClockDuration(event.dur.value());
}

return result;
}

} // namespace facebook::react::jsinspector_modern
} // namespace facebook::react::jsinspector_modern::tracing
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
#include "TraceEvent.h"
#include "TraceEventProfile.h"

#include <folly/dynamic.h>
#include <react/timing/primitives.h>

#include <folly/dynamic.h>
#include <functional>
#include <mutex>
#include <optional>
#include <vector>

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

// TODO: Review how this API is integrated into jsinspector_modern (singleton
// design is copied from earlier FuseboxTracer prototype).
Expand Down Expand Up @@ -65,7 +66,7 @@ class PerformanceTracer {
*
* See https://w3c.github.io/user-timing/#mark-method.
*/
void reportMark(const std::string_view& name, uint64_t start);
void reportMark(const std::string_view& name, HighResTimeStamp start);

/**
* Record a `Performance.measure()` event - a labelled duration. If not
Expand All @@ -75,8 +76,8 @@ class PerformanceTracer {
*/
void reportMeasure(
const std::string_view& name,
uint64_t start,
uint64_t duration,
HighResTimeStamp start,
HighResDuration duration,
const std::optional<DevToolsTrackEntryPayload>& trackMetadata);

/**
Expand All @@ -99,13 +100,13 @@ class PerformanceTracer {
* Record an Event Loop tick, which will be represented as an Event Loop task
* on a timeline view and grouped with JavaScript samples.
*/
void reportEventLoopTask(uint64_t start, uint64_t end);
void reportEventLoopTask(HighResTimeStamp start, HighResTimeStamp end);

/**
* Record Microtasks phase of the Event Loop tick. Will be represented as a
* "Run Microtasks" block under a task.
*/
void reportEventLoopMicrotasks(uint64_t start, uint64_t end);
void reportEventLoopMicrotasks(HighResTimeStamp start, HighResTimeStamp end);

/**
* Create and serialize Profile Trace Event.
Expand All @@ -114,7 +115,7 @@ class PerformanceTracer {
folly::dynamic getSerializedRuntimeProfileTraceEvent(
uint64_t threadId,
uint16_t profileId,
uint64_t eventUnixTimestamp);
HighResTimeStamp profileTimestamp);

/**
* Create and serialize ProfileChunk Trace Event.
Expand All @@ -123,8 +124,8 @@ class PerformanceTracer {
folly::dynamic getSerializedRuntimeProfileChunkTraceEvent(
uint16_t profileId,
uint64_t threadId,
uint64_t eventUnixTimestamp,
const tracing::TraceEventProfileChunk& traceEventProfileChunk);
HighResTimeStamp chunkTimestamp,
const TraceEventProfileChunk& traceEventProfileChunk);

private:
PerformanceTracer();
Expand All @@ -135,10 +136,11 @@ class PerformanceTracer {
folly::dynamic serializeTraceEvent(const TraceEvent& event) const;

bool tracing_{false};

uint64_t processId_;
uint32_t performanceMeasureCount_{0};
std::vector<TraceEvent> buffer_;
std::mutex mutex_;
};

} // namespace facebook::react::jsinspector_modern
} // namespace facebook::react::jsinspector_modern::tracing
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Pod::Spec.new do |s|
end

s.dependency "React-oscompat"
s.dependency "React-timing"

add_rn_third_party_dependencies(s)
end
Loading
Loading