diff --git a/packages/react-native/ReactCommon/jsinspector-modern/TracingAgent.cpp b/packages/react-native/ReactCommon/jsinspector-modern/TracingAgent.cpp index 226b3b3685c..e74c90c0497 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/TracingAgent.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/TracingAgent.cpp @@ -102,10 +102,10 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) { // Send response to Tracing.end request. frontendChannel_(cdp::jsonResult(req.id)); - auto dataCollectedCallback = [this](const folly::dynamic& eventsChunk) { + auto dataCollectedCallback = [this](folly::dynamic&& eventsChunk) { frontendChannel_(cdp::jsonNotification( "Tracing.dataCollected", - folly::dynamic::object("value", eventsChunk))); + folly::dynamic::object("value", std::move(eventsChunk)))); }; performanceTracer.collectEvents( dataCollectedCallback, TRACE_EVENT_CHUNK_SIZE); @@ -114,8 +114,9 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) { performanceTracer, dataCollectedCallback, PROFILE_TRACE_EVENT_CHUNK_SIZE); + auto tracingProfile = instanceAgent_->collectTracingProfile(); serializer.serializeAndNotify( - instanceAgent_->collectTracingProfile().runtimeSamplingProfile, + std::move(tracingProfile.runtimeSamplingProfile), instanceTracingStartTimestamp_); frontendChannel_(cdp::jsonNotification( diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp index 0cc49d63231..11392b88fbe 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp @@ -83,8 +83,7 @@ bool PerformanceTracer::stopTracing() { } void PerformanceTracer::collectEvents( - const std::function& - resultCallback, + const std::function& resultCallback, uint16_t chunkSize) { std::vector localBuffer; { @@ -102,12 +101,12 @@ void PerformanceTracer::collectEvents( serializedTraceEvents.push_back(serializeTraceEvent(std::move(event))); if (serializedTraceEvents.size() == chunkSize) { - resultCallback(serializedTraceEvents); + resultCallback(std::move(serializedTraceEvents)); serializedTraceEvents = folly::dynamic::array(); } } if (!serializedTraceEvents.empty()) { - resultCallback(serializedTraceEvents); + resultCallback(std::move(serializedTraceEvents)); } } diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h index d2673d7e43a..474c962e0ea 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h @@ -56,8 +56,7 @@ class PerformanceTracer { * Flush out buffered CDP Trace Events using the given callback. */ void collectEvents( - const std::function& - resultCallback, + const std::function& resultCallback, uint16_t chunkSize); /** diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.cpp index 89d568b4545..e229e75eb40 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.cpp @@ -115,7 +115,7 @@ void RuntimeSamplingProfileTraceEventSerializer::chunkEmptySample( } void RuntimeSamplingProfileTraceEventSerializer::bufferProfileChunkTraceEvent( - ProfileChunk& chunk, + ProfileChunk&& chunk, uint16_t profileId) { if (chunk.isEmpty()) { return; @@ -135,14 +135,17 @@ void RuntimeSamplingProfileTraceEventSerializer::bufferProfileChunkTraceEvent( TraceEventProfileChunk{ .cpuProfile = TraceEventProfileChunk::CPUProfile{ - traceEventNodes, chunk.samples}, + .nodes = std::move(traceEventNodes), + .samples = std::move(chunk.samples)}, .timeDeltas = - TraceEventProfileChunk::TimeDeltas{chunk.timeDeltas}, + TraceEventProfileChunk::TimeDeltas{ + .deltas = std::move(chunk.timeDeltas), + }, })); } void RuntimeSamplingProfileTraceEventSerializer::processCallStack( - const std::vector& callStack, + std::vector&& callStack, ProfileChunk& chunk, ProfileTreeNode& rootNode, uint32_t idleNodeId, @@ -184,14 +187,16 @@ void RuntimeSamplingProfileTraceEventSerializer::processCallStack( void RuntimeSamplingProfileTraceEventSerializer:: sendBufferedTraceEventsAndClear() { - notificationCallback_(traceEventBuffer_); + notificationCallback_(std::move(traceEventBuffer_)); + traceEventBuffer_ = folly::dynamic::array(); + traceEventBuffer_.reserve(traceEventChunkSize_); } void RuntimeSamplingProfileTraceEventSerializer::serializeAndNotify( - const RuntimeSamplingProfile& profile, + RuntimeSamplingProfile&& profile, HighResTimeStamp tracingStartTime) { - const std::vector& samples = profile.samples; + auto samples = std::move(profile.samples); if (samples.empty()) { return; } @@ -225,7 +230,7 @@ void RuntimeSamplingProfileTraceEventSerializer::serializeAndNotify( chunk.nodes.push_back(*idleNode); uint32_t idleNodeId = idleNode->getId(); - for (const auto& sample : samples) { + for (auto& sample : samples) { uint64_t currentSampleThreadId = sample.threadId; auto currentSampleTimestamp = getHighResTimeStampForSample(sample); @@ -234,7 +239,7 @@ void RuntimeSamplingProfileTraceEventSerializer::serializeAndNotify( // We should group samples by thread id once we support executing JavaScript // on different threads. if (currentSampleThreadId != chunk.threadId || chunk.isFull()) { - bufferProfileChunkTraceEvent(chunk, PROFILE_ID); + bufferProfileChunkTraceEvent(std::move(chunk), PROFILE_ID); chunk = ProfileChunk{ profileChunkSize_, currentSampleThreadId, currentChunkTimestamp}; } @@ -244,7 +249,7 @@ void RuntimeSamplingProfileTraceEventSerializer::serializeAndNotify( } processCallStack( - sample.callStack, + std::move(sample.callStack), chunk, rootNode, idleNodeId, @@ -255,7 +260,7 @@ void RuntimeSamplingProfileTraceEventSerializer::serializeAndNotify( } if (!chunk.isEmpty()) { - bufferProfileChunkTraceEvent(chunk, PROFILE_ID); + bufferProfileChunkTraceEvent(std::move(chunk), PROFILE_ID); } if (!traceEventBuffer_.empty()) { diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.h b/packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.h index 620d42df119..bca4a7510a5 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.h @@ -72,7 +72,7 @@ class RuntimeSamplingProfileTraceEventSerializer { */ RuntimeSamplingProfileTraceEventSerializer( PerformanceTracer& performanceTracer, - std::function + std::function notificationCallback, uint16_t traceEventChunkSize, uint16_t profileChunkSize = 10) @@ -90,7 +90,7 @@ class RuntimeSamplingProfileTraceEventSerializer { * will be used as a starting reference point of JavaScript samples recording. */ void serializeAndNotify( - const RuntimeSamplingProfile& profile, + RuntimeSamplingProfile&& profile, HighResTimeStamp tracingStartTime); private: @@ -123,7 +123,7 @@ class RuntimeSamplingProfileTraceEventSerializer { * \param chunk The chunk that will be buffered. * \param profileId The id of the Profile. */ - void bufferProfileChunkTraceEvent(ProfileChunk& chunk, uint16_t profileId); + void bufferProfileChunkTraceEvent(ProfileChunk&& chunk, uint16_t profileId); /** * Encapsulates logic for processing the call stack of the sample. @@ -140,8 +140,7 @@ class RuntimeSamplingProfileTraceEventSerializer { * generating unique node ids. */ void processCallStack( - const std::vector& - callStack, + std::vector&& callStack, ProfileChunk& chunk, ProfileTreeNode& rootNode, uint32_t idleNodeId, @@ -154,10 +153,10 @@ class RuntimeSamplingProfileTraceEventSerializer { void sendBufferedTraceEventsAndClear(); PerformanceTracer& performanceTracer_; - const std::function + const std::function notificationCallback_; - uint16_t traceEventChunkSize_; - uint16_t profileChunkSize_; + const uint16_t traceEventChunkSize_; + const uint16_t profileChunkSize_; folly::dynamic traceEventBuffer_; }; diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tracing/tests/RuntimeSamplingProfileTraceEventSerializerTest.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tracing/tests/RuntimeSamplingProfileTraceEventSerializerTest.cpp index 1303f560fba..6b1cb165eae 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tracing/tests/RuntimeSamplingProfileTraceEventSerializerTest.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tracing/tests/RuntimeSamplingProfileTraceEventSerializerTest.cpp @@ -18,9 +18,9 @@ class RuntimeSamplingProfileTraceEventSerializerTest : public ::testing::Test { protected: std::vector notificationEvents_; - std::function + std::function createNotificationCallback() { - return [this](const folly::dynamic& traceEventsChunk) { + return [this](folly::dynamic&& traceEventsChunk) { notificationEvents_.push_back(traceEventsChunk); }; } @@ -74,7 +74,7 @@ TEST_F(RuntimeSamplingProfileTraceEventSerializerTest, EmptyProfile) { auto tracingStartTime = HighResTimeStamp::now(); // Execute - serializer.serializeAndNotify(profile, tracingStartTime); + serializer.serializeAndNotify(std::move(profile), tracingStartTime); // Nothing should be reported if the profile is empty. EXPECT_TRUE(notificationEvents_.empty()); @@ -122,7 +122,7 @@ TEST_F( auto tracingStartTime = HighResTimeStamp::now(); // Execute - serializer.serializeAndNotify(profile, tracingStartTime); + serializer.serializeAndNotify(std::move(profile), tracingStartTime); // Verify ASSERT_EQ(notificationEvents_.size(), 2); @@ -155,7 +155,7 @@ TEST_F(RuntimeSamplingProfileTraceEventSerializerTest, EmptySample) { folly::dynamic chunkEvent = folly::dynamic::object; // Execute - serializer.serializeAndNotify(profile, tracingStartTime); + serializer.serializeAndNotify(std::move(profile), tracingStartTime); // Verify // [["Profile"], ["ProfileChunk"]] @@ -192,7 +192,7 @@ TEST_F( auto tracingStartTime = HighResTimeStamp::now(); // Execute - serializer.serializeAndNotify(profile, tracingStartTime); + serializer.serializeAndNotify(std::move(profile), tracingStartTime); // [["Profile"], ["ProfileChunk", "ProfileChunk", "ProfileChunk]] // Samples from different thread should never be grouped together in the same @@ -231,7 +231,7 @@ TEST_F( auto tracingStartTime = HighResTimeStamp::now(); // Execute - serializer.serializeAndNotify(profile, tracingStartTime); + serializer.serializeAndNotify(std::move(profile), tracingStartTime); // [["Profile"], ["ProfileChunk", "ProfileChunk"], ["ProfileChunk"]] ASSERT_EQ(notificationEvents_.size(), 3); @@ -272,7 +272,7 @@ TEST_F(RuntimeSamplingProfileTraceEventSerializerTest, ProfileChunkSizeLimit) { auto tracingStartTime = HighResTimeStamp::now(); // Execute - serializer.serializeAndNotify(profile, tracingStartTime); + serializer.serializeAndNotify(std::move(profile), tracingStartTime); // [["Profile"], ["ProfileChunk", "ProfileChunk", "ProfileChunk"]] ASSERT_EQ(notificationEvents_.size(), 2);