Skip to content

Commit e64dce5

Browse files
hoxyqfacebook-github-bot
authored andcommitted
Set threshold for a number of unique nodes in ProfileChunk (#53536)
Summary: Pull Request resolved: #53536 # Changelog: [Internal] For every chunk, we already have a threshold for the number of samples captured in this chunk. There could be really tall call stacks, where we could record hundreds of unique nodes, which makes the chunk already big enough for a CDP traffic on android. We are adding a threshold for a number of unique nodes in a single chunk. If the chunk has a greater number of nodes recorded, it will be dispatched over CDP. Reviewed By: huntie Differential Revision: D81339677 fbshipit-source-id: 388d14c64c4c3f60918a8526025f79d19d397cb4
1 parent 8eea166 commit e64dce5

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,15 +283,17 @@ RuntimeSamplingProfileTraceEventSerializer::serializeAndDispatch(
283283
const std::function<void(folly::dynamic&& traceEventsChunk)>&
284284
dispatchCallback,
285285
uint16_t traceEventChunkSize,
286-
uint16_t profileChunkSize) {
286+
uint16_t profileChunkSize,
287+
uint16_t maxUniqueNodesPerChunk) {
287288
for (auto&& profile : profiles) {
288289
serializeAndDispatch(
289290
std::move(profile),
290291
profileIdGenerator,
291292
tracingStartTime,
292293
dispatchCallback,
293294
traceEventChunkSize,
294-
profileChunkSize);
295+
profileChunkSize,
296+
maxUniqueNodesPerChunk);
295297
}
296298
}
297299

@@ -303,7 +305,8 @@ RuntimeSamplingProfileTraceEventSerializer::serializeAndDispatch(
303305
const std::function<void(folly::dynamic&& traceEventsChunk)>&
304306
dispatchCallback,
305307
uint16_t traceEventChunkSize,
306-
uint16_t profileChunkSize) {
308+
uint16_t profileChunkSize,
309+
uint16_t maxUniqueNodesPerChunk) {
307310
auto samples = std::move(profile.samples);
308311
if (samples.empty()) {
309312
return;
@@ -344,7 +347,8 @@ RuntimeSamplingProfileTraceEventSerializer::serializeAndDispatch(
344347
}
345348
auto& threadProfileState = threadProfileStateIterator->second;
346349

347-
if (threadProfileState.chunk.isFull()) {
350+
if (threadProfileState.chunk.isFull() ||
351+
threadProfileState.chunk.nodes.size() >= maxUniqueNodesPerChunk) {
348352
bufferProfileChunkTraceEvent(
349353
std::move(threadProfileState.chunk),
350354
threadProfileState.profileId,

packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@
1313

1414
namespace facebook::react::jsinspector_modern::tracing {
1515

16+
namespace {
17+
18+
/**
19+
* Maximum number of samples per chunk.
20+
*/
21+
constexpr uint16_t PROFILE_CHUNK_SIZE = 100;
22+
23+
/**
24+
* Maximum number of unique nodes per chunk.
25+
*/
26+
constexpr uint16_t MAX_UNIQUE_NODES_PER_CHUNK = 50;
27+
28+
} // namespace
29+
1630
struct IdGenerator {
1731
public:
1832
uint32_t getNext() {
@@ -49,7 +63,8 @@ class RuntimeSamplingProfileTraceEventSerializer {
4963
const std::function<void(folly::dynamic&& traceEventsChunk)>&
5064
dispatchCallback,
5165
uint16_t traceEventChunkSize,
52-
uint16_t profileChunkSize = 10);
66+
uint16_t profileChunkSize = PROFILE_CHUNK_SIZE,
67+
uint16_t maxUniqueNodesPerChunk = MAX_UNIQUE_NODES_PER_CHUNK);
5368

5469
static void serializeAndDispatch(
5570
std::vector<RuntimeSamplingProfile>&& profiles,
@@ -58,7 +73,8 @@ class RuntimeSamplingProfileTraceEventSerializer {
5873
const std::function<void(folly::dynamic&& traceEventsChunk)>&
5974
dispatchCallback,
6075
uint16_t traceEventChunkSize,
61-
uint16_t profileChunkSize = 10);
76+
uint16_t profileChunkSize = PROFILE_CHUNK_SIZE,
77+
uint16_t maxUniqueNodesPerChunk = MAX_UNIQUE_NODES_PER_CHUNK);
6278
};
6379

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

packages/react-native/ReactCommon/jsinspector-modern/tracing/tests/RuntimeSamplingProfileTraceEventSerializerTest.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,4 +310,51 @@ TEST_F(RuntimeSamplingProfileTraceEventSerializerTest, ProfileChunkSizeLimit) {
310310
}
311311
}
312312

313+
TEST_F(RuntimeSamplingProfileTraceEventSerializerTest, UniqueNodesThreshold) {
314+
// Setup
315+
auto notificationCallback = createNotificationCallback();
316+
IdGenerator profileIdGenerator;
317+
uint16_t traceEventChunkSize = 10;
318+
uint16_t profileChunkSize = 10;
319+
uint16_t maxUniqueNodesPerChunk = 3;
320+
321+
// Create samples with different function names to generate unique nodes
322+
ThreadId threadId = 1;
323+
uint64_t timestamp = 1000000;
324+
325+
std::vector<RuntimeSamplingProfile::Sample> samples;
326+
327+
// In total we would have 8 unique nodes, 5 of which are created here.
328+
// Other 3 are (root), (program), (idle).
329+
for (int i = 0; i < 5; i++) {
330+
std::vector<RuntimeSamplingProfile::SampleCallStackFrame> callStack = {
331+
createJSCallFrame(
332+
"function" + std::to_string(i), 1, "test.js", 10 + i, 5)};
333+
samples.push_back(createSample(timestamp + i * 1000, threadId, callStack));
334+
}
335+
336+
auto profile = createProfileWithSamples(std::move(samples));
337+
auto tracingStartTime = HighResTimeStamp::now();
338+
339+
// Execute
340+
RuntimeSamplingProfileTraceEventSerializer::serializeAndDispatch(
341+
std::move(profile),
342+
profileIdGenerator,
343+
tracingStartTime,
344+
notificationCallback,
345+
traceEventChunkSize,
346+
profileChunkSize,
347+
maxUniqueNodesPerChunk);
348+
349+
// [["Profile"], ["ProfileChunk", "ProfileChunk", "ProfileChunk"]]
350+
ASSERT_EQ(notificationEvents_.size(), 2);
351+
EXPECT_EQ(notificationEvents_[1].size(), 3);
352+
353+
// Verify that each chunk respects the unique nodes limit
354+
for (auto& profileChunk : notificationEvents_[1]) {
355+
auto& nodes = profileChunk["args"]["data"]["cpuProfile"]["nodes"];
356+
EXPECT_LE(nodes.size(), maxUniqueNodesPerChunk);
357+
}
358+
}
359+
313360
} // namespace facebook::react::jsinspector_modern::tracing

0 commit comments

Comments
 (0)