Skip to content

Commit 6659976

Browse files
mralephCommit Queue
authored andcommitted
[vm] Reduce duplication in timeline.cc
Place serialization code shared between fixed buffer and endless recorders into an abstract superclass. TEST=ci Change-Id: I643e606ec144b06406375b796f4f2b369b657d3c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/417200 Reviewed-by: Derek Xu <[email protected]> Commit-Queue: Slava Egorov <[email protected]>
1 parent 0dd150b commit 6659976

File tree

2 files changed

+81
-151
lines changed

2 files changed

+81
-151
lines changed

runtime/vm/timeline.cc

Lines changed: 44 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ void TimelineEvent::Init(EventType event_type, const char* label) {
669669
}
670670

671671
bool TimelineEvent::Within(int64_t time_origin_micros,
672-
int64_t time_extent_micros) {
672+
int64_t time_extent_micros) const {
673673
if ((time_origin_micros == -1) || (time_extent_micros == -1)) {
674674
// No time range specified.
675675
return true;
@@ -1610,9 +1610,8 @@ intptr_t TimelineEventFixedBufferRecorder::Size() {
16101610
}
16111611

16121612
#ifndef PRODUCT
1613-
void TimelineEventFixedBufferRecorder::PrintEventsCommon(
1614-
const TimelineEventFilter& filter,
1615-
std::function<void(const TimelineEvent&)>&& print_impl) {
1613+
void TimelineEventFixedBufferRecorder::ForEachNonEmptyBlock(
1614+
std::function<void(const TimelineEventBlock&)>&& handle_block) {
16161615
// Acquire the recorder's lock to prevent the reclaimed blocks from being
16171616
// handed out again until the trace has been serialized.
16181617
MutexLocker ml(&lock_);
@@ -1629,20 +1628,30 @@ void TimelineEventFixedBufferRecorder::PrintEventsCommon(
16291628
if (!block->ContainsEventsThatCanBeSerializedLocked()) {
16301629
continue;
16311630
}
1632-
for (intptr_t event_idx = 0; event_idx < block->length(); event_idx++) {
1633-
TimelineEvent* event = block->At(event_idx);
1634-
if (filter.IncludeEvent(event) &&
1635-
event->Within(filter.time_origin_micros(),
1636-
filter.time_extent_micros())) {
1637-
ReportTime(event->LowTime());
1638-
ReportTime(event->HighTime());
1639-
print_impl(*event);
1640-
}
1641-
}
1631+
handle_block(*block);
16421632
}
16431633
}
16441634

1645-
void TimelineEventFixedBufferRecorder::PrintJSONEvents(
1635+
void TimelineEventBufferedRecorder::PrintEventsCommon(
1636+
const TimelineEventFilter& filter,
1637+
std::function<void(const TimelineEvent&)>&& print_impl) {
1638+
ForEachNonEmptyBlock(
1639+
[this, &filter, print_impl = std::move(print_impl)](auto& block) {
1640+
for (intptr_t event_idx = 0, length = block.length();
1641+
event_idx < length; event_idx++) {
1642+
auto event = block.At(event_idx);
1643+
if (filter.IncludeEvent(event) &&
1644+
event->Within(filter.time_origin_micros(),
1645+
filter.time_extent_micros())) {
1646+
ReportTime(event->LowTime());
1647+
ReportTime(event->HighTime());
1648+
print_impl(*event);
1649+
}
1650+
}
1651+
});
1652+
}
1653+
1654+
void TimelineEventBufferedRecorder::PrintJSONEvents(
16461655
const JSONArray& events,
16471656
const TimelineEventFilter& filter) {
16481657
PrintEventsCommon(filter, [&events](const TimelineEvent& event) {
@@ -1704,7 +1713,7 @@ inline void PrintPerfettoEventCallbackBody(
17041713
heap_buffered_packet->Reset();
17051714
}
17061715

1707-
void TimelineEventFixedBufferRecorder::PrintPerfettoEvents(
1716+
void TimelineEventBufferedRecorder::PrintPerfettoEvents(
17081717
JSONBase64String* jsonBase64String,
17091718
const TimelineEventFilter& filter) {
17101719
PrintEventsCommon(
@@ -1721,8 +1730,8 @@ void TimelineEventFixedBufferRecorder::PrintPerfettoEvents(
17211730
}
17221731
#endif // defined(SUPPORT_PERFETTO)
17231732

1724-
void TimelineEventFixedBufferRecorder::PrintJSON(JSONStream* js,
1725-
TimelineEventFilter* filter) {
1733+
void TimelineEventBufferedRecorder::PrintJSON(JSONStream* js,
1734+
TimelineEventFilter* filter) {
17261735
JSONObject topLevel(js);
17271736
topLevel.AddProperty("type", "Timeline");
17281737
{
@@ -1734,30 +1743,26 @@ void TimelineEventFixedBufferRecorder::PrintJSON(JSONStream* js,
17341743
topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros());
17351744
}
17361745

1737-
#define PRINT_PERFETTO_TIMELINE_BODY \
1738-
JSONObject jsobj_topLevel(js); \
1739-
jsobj_topLevel.AddProperty("type", "PerfettoTimeline"); \
1740-
\
1741-
js->AppendSerializedObject("\"trace\":"); \
1742-
{ \
1743-
JSONBase64String jsonBase64String(js); \
1744-
PrintPerfettoMeta(&jsonBase64String); \
1745-
PrintPerfettoEvents(&jsonBase64String, filter); \
1746-
} \
1747-
\
1748-
jsobj_topLevel.AddPropertyTimeMicros("timeOriginMicros", \
1749-
TimeOriginMicros()); \
1750-
jsobj_topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros());
1751-
17521746
#if defined(SUPPORT_PERFETTO)
1753-
void TimelineEventFixedBufferRecorder::PrintPerfettoTimeline(
1747+
void TimelineEventBufferedRecorder::PrintPerfettoTimeline(
17541748
JSONStream* js,
17551749
const TimelineEventFilter& filter) {
1756-
PRINT_PERFETTO_TIMELINE_BODY
1750+
JSONObject jsobj_topLevel(js);
1751+
jsobj_topLevel.AddProperty("type", "PerfettoTimeline");
1752+
1753+
js->AppendSerializedObject("\"trace\":");
1754+
{
1755+
JSONBase64String jsonBase64String(js);
1756+
PrintPerfettoMeta(&jsonBase64String);
1757+
PrintPerfettoEvents(&jsonBase64String, filter);
1758+
}
1759+
1760+
jsobj_topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros());
1761+
jsobj_topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros());
17571762
}
17581763
#endif // defined(SUPPORT_PERFETTO)
17591764

1760-
void TimelineEventFixedBufferRecorder::PrintTraceEvent(
1765+
void TimelineEventBufferedRecorder::PrintTraceEvent(
17611766
JSONStream* js,
17621767
TimelineEventFilter* filter) {
17631768
JSONArray events(js);
@@ -2225,9 +2230,8 @@ TimelineEventEndlessRecorder::~TimelineEventEndlessRecorder() {
22252230
}
22262231

22272232
#ifndef PRODUCT
2228-
void TimelineEventEndlessRecorder::PrintEventsCommon(
2229-
const TimelineEventFilter& filter,
2230-
std::function<void(const TimelineEvent&)>&& print_impl) {
2233+
void TimelineEventEndlessRecorder::ForEachNonEmptyBlock(
2234+
std::function<void(const TimelineEventBlock&)>&& handle_block) {
22312235
// Acquire the recorder's lock to prevent the reclaimed blocks from being
22322236
// handed out again until the trace has been serialized.
22332237
MutexLocker ml(&lock_);
@@ -2238,74 +2242,9 @@ void TimelineEventEndlessRecorder::PrintEventsCommon(
22382242
if (!current->ContainsEventsThatCanBeSerializedLocked()) {
22392243
continue;
22402244
}
2241-
intptr_t length = current->length();
2242-
for (intptr_t i = 0; i < length; i++) {
2243-
TimelineEvent* event = current->At(i);
2244-
if (filter.IncludeEvent(event) &&
2245-
event->Within(filter.time_origin_micros(),
2246-
filter.time_extent_micros())) {
2247-
ReportTime(event->LowTime());
2248-
ReportTime(event->HighTime());
2249-
print_impl(*event);
2250-
}
2251-
}
2245+
handle_block(*current);
22522246
}
22532247
}
2254-
2255-
void TimelineEventEndlessRecorder::PrintJSONEvents(
2256-
const JSONArray& events,
2257-
const TimelineEventFilter& filter) {
2258-
PrintEventsCommon(filter, [&events](const TimelineEvent& event) {
2259-
events.AddValue(&event);
2260-
});
2261-
}
2262-
2263-
#if defined(SUPPORT_PERFETTO)
2264-
void TimelineEventEndlessRecorder::PrintPerfettoEvents(
2265-
JSONBase64String* jsonBase64String,
2266-
const TimelineEventFilter& filter) {
2267-
PrintEventsCommon(
2268-
filter, [this, &jsonBase64String](const TimelineEvent& event) {
2269-
PrintPerfettoEventCallbackBody(
2270-
&packet(), event,
2271-
[&jsonBase64String](
2272-
protozero::HeapBuffered<perfetto::protos::pbzero::TracePacket>*
2273-
packet) {
2274-
perfetto_utils::AppendPacketToJSONBase64String(jsonBase64String,
2275-
packet);
2276-
});
2277-
});
2278-
}
2279-
#endif // defined(SUPPORT_PERFETTO)
2280-
2281-
void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js,
2282-
TimelineEventFilter* filter) {
2283-
JSONObject topLevel(js);
2284-
topLevel.AddProperty("type", "Timeline");
2285-
{
2286-
JSONArray events(&topLevel, "traceEvents");
2287-
PrintJSONMeta(events);
2288-
PrintJSONEvents(events, *filter);
2289-
}
2290-
topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros());
2291-
topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros());
2292-
}
2293-
2294-
#if defined(SUPPORT_PERFETTO)
2295-
void TimelineEventEndlessRecorder::PrintPerfettoTimeline(
2296-
JSONStream* js,
2297-
const TimelineEventFilter& filter) {
2298-
PRINT_PERFETTO_TIMELINE_BODY
2299-
}
2300-
#endif // defined(SUPPORT_PERFETTO)
2301-
2302-
void TimelineEventEndlessRecorder::PrintTraceEvent(
2303-
JSONStream* js,
2304-
TimelineEventFilter* filter) {
2305-
JSONArray events(js);
2306-
PrintJSONMeta(events);
2307-
PrintJSONEvents(events, *filter);
2308-
}
23092248
#endif // !defined(PRODUCT)
23102249

23112250
TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() {

runtime/vm/timeline.h

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ class TimelineEvent {
533533
}
534534
}
535535

536-
bool Within(int64_t time_origin_micros, int64_t time_extent_micros);
536+
bool Within(int64_t time_origin_micros, int64_t time_extent_micros) const;
537537

538538
void set_owns_label(bool owns_label) {
539539
state_ = OwnsLabelBit::update(owns_label, state_);
@@ -846,7 +846,7 @@ class TimelineEventFilter : public ValueObject {
846846

847847
virtual ~TimelineEventFilter();
848848

849-
virtual bool IncludeEvent(TimelineEvent* event) const {
849+
virtual bool IncludeEvent(const TimelineEvent* event) const {
850850
if (event == nullptr) {
851851
return false;
852852
}
@@ -868,7 +868,7 @@ class IsolateTimelineEventFilter : public TimelineEventFilter {
868868
int64_t time_origin_micros = -1,
869869
int64_t time_extent_micros = -1);
870870

871-
bool IncludeEvent(TimelineEvent* event) const final {
871+
bool IncludeEvent(const TimelineEvent* event) const final {
872872
return event->IsValid() && (event->isolate_id() == isolate_id_);
873873
}
874874

@@ -977,22 +977,42 @@ class TimelineEventRecorder : public MallocAllocated {
977977
DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder);
978978
};
979979

980-
// An abstract recorder that stores events in a buffer of fixed capacity.
981-
class TimelineEventFixedBufferRecorder : public TimelineEventRecorder {
980+
// An abstract recorder that buffers recorded events.
981+
class TimelineEventBufferedRecorder : public TimelineEventRecorder {
982982
public:
983-
static constexpr intptr_t kDefaultCapacity = 32 * KB; // Number of events.
984-
985-
explicit TimelineEventFixedBufferRecorder(intptr_t capacity);
986-
virtual ~TimelineEventFixedBufferRecorder();
987-
988983
#ifndef PRODUCT
989984
void PrintJSON(JSONStream* js, TimelineEventFilter* filter) final;
990985
#if defined(SUPPORT_PERFETTO)
991986
void PrintPerfettoTimeline(JSONStream* js,
992987
const TimelineEventFilter& filter) final;
993988
#endif // defined(SUPPORT_PERFETTO)
994989
void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter) final;
990+
991+
private:
992+
virtual void ForEachNonEmptyBlock(
993+
std::function<void(const TimelineEventBlock&)>&& handle_block) = 0;
994+
995+
void PrintJSONEvents(const JSONArray& array,
996+
const TimelineEventFilter& filter);
997+
998+
#if defined(SUPPORT_PERFETTO)
999+
void PrintPerfettoEvents(JSONBase64String* jsonBase64String,
1000+
const TimelineEventFilter& filter);
1001+
#endif // defined(SUPPORT_PERFETTO)
1002+
1003+
void PrintEventsCommon(
1004+
const TimelineEventFilter& filter,
1005+
std::function<void(const TimelineEvent&)>&& print_impl);
9951006
#endif // !defined(PRODUCT)
1007+
};
1008+
1009+
// An abstract recorder that stores events in a buffer of fixed capacity.
1010+
class TimelineEventFixedBufferRecorder : public TimelineEventBufferedRecorder {
1011+
public:
1012+
static constexpr intptr_t kDefaultCapacity = 32 * KB; // Number of events.
1013+
1014+
explicit TimelineEventFixedBufferRecorder(intptr_t capacity);
1015+
virtual ~TimelineEventFixedBufferRecorder();
9961016

9971017
intptr_t Size();
9981018

@@ -1004,26 +1024,16 @@ class TimelineEventFixedBufferRecorder : public TimelineEventRecorder {
10041024
intptr_t FindOldestBlockIndexLocked() const;
10051025
void ClearLocked();
10061026

1007-
#ifndef PRODUCT
1008-
void PrintJSONEvents(const JSONArray& array,
1009-
const TimelineEventFilter& filter);
1010-
#if defined(SUPPORT_PERFETTO)
1011-
void PrintPerfettoEvents(JSONBase64String* jsonBase64String,
1012-
const TimelineEventFilter& filter);
1013-
#endif // defined(SUPPORT_PERFETTO)
1014-
#endif // !defined(PRODUCT)
1015-
10161027
VirtualMemory* memory_;
10171028
TimelineEventBlock* blocks_;
10181029
intptr_t capacity_;
10191030
intptr_t num_blocks_;
10201031
intptr_t block_cursor_;
10211032

10221033
private:
1023-
#if !defined(PRODUCT)
1024-
inline void PrintEventsCommon(
1025-
const TimelineEventFilter& filter,
1026-
std::function<void(const TimelineEvent&)>&& print_impl);
1034+
#ifndef PRODUCT
1035+
void ForEachNonEmptyBlock(
1036+
std::function<void(const TimelineEventBlock&)>&& handle_block) final;
10271037
#endif // !defined(PRODUCT)
10281038
};
10291039

@@ -1109,20 +1119,11 @@ class TimelineEventNopRecorder : public TimelineEventCallbackRecorder {
11091119
// A recorder that stores events in chains of blocks of events.
11101120
// NOTE: This recorder will continue to allocate blocks until it exhausts
11111121
// memory.
1112-
class TimelineEventEndlessRecorder : public TimelineEventRecorder {
1122+
class TimelineEventEndlessRecorder : public TimelineEventBufferedRecorder {
11131123
public:
11141124
TimelineEventEndlessRecorder();
11151125
virtual ~TimelineEventEndlessRecorder();
11161126

1117-
#ifndef PRODUCT
1118-
void PrintJSON(JSONStream* js, TimelineEventFilter* filter) final;
1119-
#if defined(SUPPORT_PERFETTO)
1120-
void PrintPerfettoTimeline(JSONStream* js,
1121-
const TimelineEventFilter& filter) final;
1122-
#endif // defined(SUPPORT_PERFETTO)
1123-
void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter) final;
1124-
#endif // !defined(PRODUCT)
1125-
11261127
const char* name() const { return ENDLESS_RECORDER_NAME; }
11271128
intptr_t Size() { return block_index_ * sizeof(TimelineEventBlock); }
11281129

@@ -1133,24 +1134,14 @@ class TimelineEventEndlessRecorder : public TimelineEventRecorder {
11331134
TimelineEventBlock* GetHeadBlockLocked();
11341135
void ClearLocked();
11351136

1136-
#ifndef PRODUCT
1137-
void PrintJSONEvents(const JSONArray& array,
1138-
const TimelineEventFilter& filter);
1139-
#if defined(SUPPORT_PERFETTO)
1140-
void PrintPerfettoEvents(JSONBase64String* jsonBase64String,
1141-
const TimelineEventFilter& filter);
1142-
#endif // defined(SUPPORT_PERFETTO)
1143-
#endif // !defined(PRODUCT)
1144-
11451137
TimelineEventBlock* head_;
11461138
TimelineEventBlock* tail_;
11471139
intptr_t block_index_;
11481140

11491141
private:
1150-
#if !defined(PRODUCT)
1151-
inline void PrintEventsCommon(
1152-
const TimelineEventFilter& filter,
1153-
std::function<void(const TimelineEvent&)>&& print_impl);
1142+
#ifndef PRODUCT
1143+
void ForEachNonEmptyBlock(
1144+
std::function<void(const TimelineEventBlock&)>&& handle_block) final;
11541145
#endif // !defined(PRODUCT)
11551146

11561147
friend class TimelineTestHelper;

0 commit comments

Comments
 (0)