Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: runtime/vm/timeline.h

Issue 1173333007: Refactor some Timeline interfaces to be simpler and support streaming (Closed) Base URL: git@github.com:dart-lang/sdk.git@timeline2
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/service_isolate.cc ('k') | runtime/vm/timeline.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_TIMELINE_H_ 5 #ifndef VM_TIMELINE_H_
6 #define VM_TIMELINE_H_ 6 #define VM_TIMELINE_H_
7 7
8 #include "vm/bitfield.h" 8 #include "vm/bitfield.h"
9 9
10 namespace dart { 10 namespace dart {
11 11
12 class JSONStream; 12 class JSONStream;
13 class Object; 13 class Object;
14 class RawArray; 14 class RawArray;
15 class Thread; 15 class Thread;
16 class TimelineEvent; 16 class TimelineEvent;
17 class TimelineEventBuffer; 17 class TimelineEventRecorder;
18 class TimelineStream; 18 class TimelineStream;
19 19
20 // You should get a |TimelineEvent| from a |TimelineStream|.
20 class TimelineEvent { 21 class TimelineEvent {
21 public: 22 public:
22 // Keep in sync with StateBits below. 23 // Keep in sync with StateBits below.
23 enum EventType { 24 enum EventType {
24 kNone, 25 kNone,
25 kDuration, 26 kDuration,
26 kInstant, 27 kInstant,
27 kAsyncBegin, 28 kAsyncBegin,
28 kAsyncInstant, 29 kAsyncInstant,
29 kAsyncEnd, 30 kAsyncEnd,
30 kNumEventTypes, 31 kNumEventTypes,
31 }; 32 };
32 33
33 TimelineEvent(); 34 TimelineEvent();
34 ~TimelineEvent(); 35 ~TimelineEvent();
35 36
36 void Reset(); 37 void Reset();
37 38
38 bool IsValid() const { 39 bool IsValid() const {
39 return (event_type() > kNone) && (event_type() < kNumEventTypes); 40 return (event_type() > kNone) && (event_type() < kNumEventTypes);
40 } 41 }
41 42
42 // Marks the beginning of an asynchronous operation. 43 // Marks the beginning of an asynchronous operation.
43 // Returns |async_id| which must be passed to |AsyncInstant| and |AsyncEnd|. 44 // Returns |async_id| which must be passed to |AsyncInstant| and |AsyncEnd|.
44 int64_t AsyncBegin(TimelineStream* stream, const char* label); 45 int64_t AsyncBegin(const char* label);
45 // Marks an instantaneous event associated with |async_id|. 46 // Marks an instantaneous event associated with |async_id|.
46 void AsyncInstant(TimelineStream* stream, 47 void AsyncInstant(const char* label,
47 const char* label,
48 int64_t async_id); 48 int64_t async_id);
49 // Marks the end of an asynchronous operation associated with |async_id|. 49 // Marks the end of an asynchronous operation associated with |async_id|.
50 void AsyncEnd(TimelineStream* stream, 50 void AsyncEnd(const char* label,
51 const char* label,
52 int64_t async_id); 51 int64_t async_id);
53 52
54 void DurationBegin(TimelineStream* stream, const char* label); 53 void DurationBegin(const char* label);
55 void DurationEnd(); 54 void DurationEnd();
56 void Instant(TimelineStream* stream, const char* label); 55 void Instant(const char* label);
57 56
58 void Duration(TimelineStream* stream, 57 void Duration(const char* label,
59 const char* label,
60 int64_t start_micros, 58 int64_t start_micros,
61 int64_t end_micros); 59 int64_t end_micros);
62 60
63 // Set the number of arguments in the event. 61 // Set the number of arguments in the event.
64 void SetNumArguments(intptr_t length); 62 void SetNumArguments(intptr_t length);
65 // |name| must be a compile time constant. Takes ownership of |argumentp|. 63 // |name| must be a compile time constant. Takes ownership of |argumentp|.
66 void SetArgument(intptr_t i, const char* name, char* argument); 64 void SetArgument(intptr_t i, const char* name, char* argument);
67 // |name| must be a compile time constant. Copies |argument|. 65 // |name| must be a compile time constant. Copies |argument|.
68 void CopyArgument(intptr_t i, const char* name, const char* argument); 66 void CopyArgument(intptr_t i, const char* name, const char* argument);
69 // |name| must be a compile time constant. 67 // |name| must be a compile time constant.
70 void FormatArgument(intptr_t i, 68 void FormatArgument(intptr_t i,
71 const char* name, 69 const char* name,
72 const char* fmt, ...) PRINTF_ATTRIBUTE(4, 5); 70 const char* fmt, ...) PRINTF_ATTRIBUTE(4, 5);
71
72 // Mandatory to call when this event is completely filled out.
73 void Complete();
74
73 EventType event_type() const { 75 EventType event_type() const {
74 return EventTypeField::decode(state_); 76 return EventTypeField::decode(state_);
75 } 77 }
76 78
77 int64_t TimeOrigin() const; 79 int64_t TimeOrigin() const;
78 int64_t AsyncId() const; 80 int64_t AsyncId() const;
79 int64_t TimeDuration() const; 81 int64_t TimeDuration() const;
80 82
81 void PrintJSON(JSONStream* stream) const; 83 void PrintJSON(JSONStream* stream) const;
82 84
83 private: 85 private:
84 struct TimelineEventArgument { 86 struct TimelineEventArgument {
85 const char* name; 87 const char* name;
86 char* value; 88 char* value;
87 }; 89 };
88 90
89 int64_t timestamp0_; 91 int64_t timestamp0_;
90 int64_t timestamp1_; 92 int64_t timestamp1_;
91 TimelineEventArgument* arguments_; 93 TimelineEventArgument* arguments_;
92 intptr_t arguments_length_; 94 intptr_t arguments_length_;
93 uword state_; 95 uword state_;
94 const char* label_; 96 const char* label_;
95 TimelineStream* stream_; 97 TimelineStream* stream_;
96 Thread* thread_; 98 Thread* thread_;
97 99
98 void FreeArguments(); 100 void FreeArguments();
99 101
100 void Init(EventType event_type, TimelineStream* stream, const char* label); 102 void StreamInit(TimelineStream* stream);
103 void Init(EventType event_type, const char* label);
101 104
102 void set_event_type(EventType event_type) { 105 void set_event_type(EventType event_type) {
103 state_ = EventTypeField::update(event_type, state_); 106 state_ = EventTypeField::update(event_type, state_);
104 } 107 }
105 108
106 enum StateBits { 109 enum StateBits {
107 kEventTypeBit = 0, 110 kEventTypeBit = 0,
108 // reserve 4 bits for type. 111 // reserve 4 bits for type.
109 kNextBit = 4, 112 kNextBit = 4,
110 }; 113 };
111 114
112 class EventTypeField : public BitField<EventType, kEventTypeBit, 4> {}; 115 class EventTypeField : public BitField<EventType, kEventTypeBit, 4> {};
113 116
117 friend class TimelineTestHelper;
118 friend class TimelineStream;
114 DISALLOW_COPY_AND_ASSIGN(TimelineEvent); 119 DISALLOW_COPY_AND_ASSIGN(TimelineEvent);
115 }; 120 };
116 121
117 122
118 // A stream of timeline events. A stream has a name and can be enabled or 123 // A stream of timeline events. A stream has a name and can be enabled or
119 // disabled. 124 // disabled.
120 class TimelineStream { 125 class TimelineStream {
121 public: 126 public:
122 TimelineStream(); 127 TimelineStream();
123 128
124 void Init(const char* name, bool enabled); 129 void Init(const char* name, bool enabled);
125 130
126 const char* name() const { 131 const char* name() const {
127 return name_; 132 return name_;
128 } 133 }
129 134
130 bool enabled() const { 135 bool enabled() const {
131 return enabled_; 136 return enabled_;
132 } 137 }
133 138
134 void set_enabled(bool enabled) { 139 void set_enabled(bool enabled) {
135 enabled_ = enabled; 140 enabled_ = enabled;
136 } 141 }
137 142
138 TimelineEventBuffer* buffer() const { 143 TimelineEventRecorder* recorder() const {
139 return buffer_; 144 return recorder_;
140 } 145 }
141 146
142 void set_buffer(TimelineEventBuffer* buffer) { 147 // TODO(johnmccutchan): Disallow setting recorder after Init?
143 buffer_ = buffer; 148 void set_recorder(TimelineEventRecorder* recorder) {
149 recorder_ = recorder;
144 } 150 }
145 151
146 // Records an event. Will return |NULL| if not enabled. The returned 152 // Records an event. Will return |NULL| if not enabled. The returned
147 // |TimelineEvent| is in an undefined state and must be initialized. 153 // |TimelineEvent| is in an undefined state and must be initialized.
148 // |obj| is associated with the returned |TimelineEvent|. 154 // |obj| is associated with the returned |TimelineEvent|.
149 TimelineEvent* RecordEvent(const Object& obj); 155 TimelineEvent* StartEvent(const Object& obj);
150 156
151 // Records an event. Will return |NULL| if not enabled. The returned 157 // Records an event. Will return |NULL| if not enabled. The returned
152 // |TimelineEvent| is in an undefined state and must be initialized. 158 // |TimelineEvent| is in an undefined state and must be initialized.
153 TimelineEvent* RecordEvent(); 159 TimelineEvent* StartEvent();
160
161 void CompleteEvent(TimelineEvent* event);
154 162
155 int64_t GetNextSeq(); 163 int64_t GetNextSeq();
156 164
157 private: 165 private:
158 // Buffer of TimelineEvents. 166 TimelineEventRecorder* recorder_;
159 TimelineEventBuffer* buffer_;
160 const char* name_; 167 const char* name_;
161 bool enabled_; 168 bool enabled_;
162 int64_t seq_; 169 int64_t seq_;
163 }; 170 };
164 171
165 172
166 // (name, enabled by default). 173 // (name, enabled by default).
167 #define ISOLATE_TIMELINE_STREAM_LIST(V) \ 174 #define ISOLATE_TIMELINE_STREAM_LIST(V) \
168 V(API, false) \ 175 V(API, false) \
169 V(Compiler, false) \ 176 V(Compiler, false) \
(...skipping 13 matching lines...) Expand all
183 "function", \ 190 "function", \
184 const_cast<char*>(function.QualifiedUserVisibleNameCString())); \ 191 const_cast<char*>(function.QualifiedUserVisibleNameCString())); \
185 } 192 }
186 193
187 class TimelineDurationScope : public StackResource { 194 class TimelineDurationScope : public StackResource {
188 public: 195 public:
189 TimelineDurationScope(Isolate* isolate, 196 TimelineDurationScope(Isolate* isolate,
190 TimelineStream* stream, 197 TimelineStream* stream,
191 const char* label) 198 const char* label)
192 : StackResource(isolate) { 199 : StackResource(isolate) {
193 event_ = stream->RecordEvent(); 200 event_ = stream->StartEvent();
194 if (event_ == NULL) { 201 if (event_ == NULL) {
195 return; 202 return;
196 } 203 }
197 event_->DurationBegin(stream, label); 204 event_->DurationBegin(label);
198 } 205 }
199 206
200 bool enabled() const { 207 bool enabled() const {
201 return event_ != NULL; 208 return event_ != NULL;
202 } 209 }
203 210
204 void SetNumArguments(intptr_t length) { 211 void SetNumArguments(intptr_t length) {
205 if (event_ == NULL) { 212 if (event_ == NULL) {
206 return; 213 return;
207 } 214 }
(...skipping 16 matching lines...) Expand all
224 231
225 void FormatArgument(intptr_t i, 232 void FormatArgument(intptr_t i,
226 const char* name, 233 const char* name,
227 const char* fmt, ...) PRINTF_ATTRIBUTE(4, 5); 234 const char* fmt, ...) PRINTF_ATTRIBUTE(4, 5);
228 235
229 ~TimelineDurationScope() { 236 ~TimelineDurationScope() {
230 if (event_ == NULL) { 237 if (event_ == NULL) {
231 return; 238 return;
232 } 239 }
233 event_->DurationEnd(); 240 event_->DurationEnd();
241 event_->Complete();
234 } 242 }
235 243
236 private: 244 private:
237 TimelineEvent* event_; 245 TimelineEvent* event_;
238 }; 246 };
239 247
240 248
241 class TimelineEventBuffer { 249 // Recorder of |TimelineEvent|s.
250 class TimelineEventRecorder {
251 public:
252 TimelineEventRecorder();
253 virtual ~TimelineEventRecorder() {}
254
255 // Interface method(s) which must be implemented.
256 virtual void PrintJSON(JSONStream* js) const = 0;
257
258 void WriteTo(const char* directory);
259
260 protected:
261 // Interface method(s) which must be implemented.
262 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor) = 0;
263 virtual TimelineEvent* StartEvent(const Object& object) = 0;
264 virtual TimelineEvent* StartEvent() = 0;
265 virtual void CompleteEvent(TimelineEvent* event) = 0;
266
267 // Utility method(s).
268 void PrintJSONMeta(JSONArray* array) const;
269
270 friend class TimelineStream;
271 friend class Isolate;
272
273 private:
274 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder);
275 };
276
277
278 // A recorder that stores events in a ring buffer of fixed capacity.
279 class TimelineEventRingRecorder : public TimelineEventRecorder {
242 public: 280 public:
243 static const intptr_t kDefaultCapacity = 8192; 281 static const intptr_t kDefaultCapacity = 8192;
244 282
245 static intptr_t SizeForCapacity(intptr_t capacity); 283 static intptr_t SizeForCapacity(intptr_t capacity);
246 284
247 explicit TimelineEventBuffer(intptr_t capacity = kDefaultCapacity); 285 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity);
248 ~TimelineEventBuffer(); 286 ~TimelineEventRingRecorder();
249 287
250 void PrintJSON(JSONStream* js) const; 288 void PrintJSON(JSONStream* js) const;
251 289
252 void WriteTo(const char* directory); 290 protected:
291 void VisitObjectPointers(ObjectPointerVisitor* visitor);
292 TimelineEvent* StartEvent(const Object& object);
293 TimelineEvent* StartEvent();
294 void CompleteEvent(TimelineEvent* event);
253 295
254 private: 296 void PrintJSONEvents(JSONArray* array) const;
297
298 intptr_t GetNextIndex();
299
255 // events_[i] and event_objects_[i] are indexed together. 300 // events_[i] and event_objects_[i] are indexed together.
256 TimelineEvent* events_; 301 TimelineEvent* events_;
257 RawArray* event_objects_; 302 RawArray* event_objects_;
258 uintptr_t cursor_; 303 uintptr_t cursor_;
259 intptr_t capacity_; 304 intptr_t capacity_;
305 };
260 306
261 void PrintJSONMeta(JSONArray* array) const;
262 void PrintJSONEvents(JSONArray* array) const;
263 307
264 intptr_t GetNextIndex(); 308 // An abstract recorder that calls |StreamEvent| whenever an event is complete.
309 // This recorder does not track Dart objects.
310 class TimelineEventStreamingRecorder : public TimelineEventRecorder {
311 public:
312 TimelineEventStreamingRecorder();
313 ~TimelineEventStreamingRecorder();
314
315 void PrintJSON(JSONStream* js) const;
316
317 // Called when |event| is ready to be streamed. It is unsafe to keep a
318 // reference to |event| as it may be freed as soon as this function returns.
319 virtual void StreamEvent(TimelineEvent* event) = 0;
320
321 protected:
265 void VisitObjectPointers(ObjectPointerVisitor* visitor); 322 void VisitObjectPointers(ObjectPointerVisitor* visitor);
266 TimelineEvent* RecordEvent(const Object& obj); 323 TimelineEvent* StartEvent(const Object& object);
267 TimelineEvent* RecordEvent(); 324 TimelineEvent* StartEvent();
268 325 void CompleteEvent(TimelineEvent* event);
269 friend class TimelineStream;
270 friend class Isolate;
271 DISALLOW_COPY_AND_ASSIGN(TimelineEventBuffer);
272 }; 326 };
273 327
274 } // namespace dart 328 } // namespace dart
275 329
276 #endif // VM_TIMELINE_H_ 330 #endif // VM_TIMELINE_H_
OLDNEW
« no previous file with comments | « runtime/vm/service_isolate.cc ('k') | runtime/vm/timeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698