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

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

Issue 1275113003: Endless thread safe timeline recorder (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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/thread.h ('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 TimelineEventBlock;
17 class TimelineEventRecorder; 18 class TimelineEventRecorder;
18 class TimelineStream; 19 class TimelineStream;
19 20
20 // You should get a |TimelineEvent| from a |TimelineStream|. 21 // You should get a |TimelineEvent| from a |TimelineStream|.
21 class TimelineEvent { 22 class TimelineEvent {
22 public: 23 public:
23 // Keep in sync with StateBits below. 24 // Keep in sync with StateBits below.
24 enum EventType { 25 enum EventType {
25 kNone, 26 kNone,
26 kDuration, 27 kDuration,
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 } 240 }
240 event_->DurationEnd(); 241 event_->DurationEnd();
241 event_->Complete(); 242 event_->Complete();
242 } 243 }
243 244
244 private: 245 private:
245 TimelineEvent* event_; 246 TimelineEvent* event_;
246 }; 247 };
247 248
248 249
250 // A block of |TimelineEvent|s. Not thread safe.
251 class TimelineEventBlock {
252 public:
253 static const intptr_t kBlockSize = 64;
254
255 TimelineEventBlock();
256
257 TimelineEventBlock* next() const {
258 return next_;
259 }
260 void set_next(TimelineEventBlock* next) {
261 next_ = next;
262 }
263
264 intptr_t length() const {
265 return length_;
266 }
267
268 bool IsFull() const {
269 return length_ == kBlockSize;
270 }
271
272 TimelineEvent* At(intptr_t index) {
273 ASSERT(index >= 0);
274 ASSERT(index < kBlockSize);
275 return &events_[index];
276 }
277
278 protected:
279 TimelineEvent* StartEvent();
280
281 TimelineEvent events_[kBlockSize];
282 TimelineEventBlock* next_;
283 intptr_t length_;
284
285 friend class TimelineEventEndlessRecorder;
286
287 private:
288 DISALLOW_COPY_AND_ASSIGN(TimelineEventBlock);
289 };
290
291
249 // Recorder of |TimelineEvent|s. 292 // Recorder of |TimelineEvent|s.
250 class TimelineEventRecorder { 293 class TimelineEventRecorder {
251 public: 294 public:
252 TimelineEventRecorder(); 295 TimelineEventRecorder();
253 virtual ~TimelineEventRecorder() {} 296 virtual ~TimelineEventRecorder() {}
254 297
255 // Interface method(s) which must be implemented. 298 // Interface method(s) which must be implemented.
256 virtual void PrintJSON(JSONStream* js) const = 0; 299 virtual void PrintJSON(JSONStream* js) = 0;
300
301 // Override if recorder uses blocks.
302 virtual TimelineEventBlock* GetNewBlock() {
303 return NULL;
304 }
257 305
258 void WriteTo(const char* directory); 306 void WriteTo(const char* directory);
259 307
260 protected: 308 protected:
261 // Interface method(s) which must be implemented. 309 // Interface method(s) which must be implemented.
262 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor) = 0; 310 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor) = 0;
263 virtual TimelineEvent* StartEvent(const Object& object) = 0; 311 virtual TimelineEvent* StartEvent(const Object& object) = 0;
264 virtual TimelineEvent* StartEvent() = 0; 312 virtual TimelineEvent* StartEvent() = 0;
265 virtual void CompleteEvent(TimelineEvent* event) = 0; 313 virtual void CompleteEvent(TimelineEvent* event) = 0;
266 314
267 // Utility method(s). 315 // Utility method(s).
268 void PrintJSONMeta(JSONArray* array) const; 316 void PrintJSONMeta(JSONArray* array) const;
269 317
270 friend class TimelineStream; 318 friend class TimelineStream;
271 friend class Isolate; 319 friend class Isolate;
272 320
273 private: 321 private:
274 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); 322 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder);
275 }; 323 };
276 324
277 325
278 // A recorder that stores events in a ring buffer of fixed capacity. 326 // A recorder that stores events in a ring buffer of fixed capacity.
327 // This recorder does track Dart objects.
279 class TimelineEventRingRecorder : public TimelineEventRecorder { 328 class TimelineEventRingRecorder : public TimelineEventRecorder {
280 public: 329 public:
281 static const intptr_t kDefaultCapacity = 8192; 330 static const intptr_t kDefaultCapacity = 8192;
282 331
283 static intptr_t SizeForCapacity(intptr_t capacity); 332 static intptr_t SizeForCapacity(intptr_t capacity);
284 333
285 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); 334 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity);
286 ~TimelineEventRingRecorder(); 335 ~TimelineEventRingRecorder();
287 336
288 void PrintJSON(JSONStream* js) const; 337 void PrintJSON(JSONStream* js);
289 338
290 protected: 339 protected:
291 void VisitObjectPointers(ObjectPointerVisitor* visitor); 340 void VisitObjectPointers(ObjectPointerVisitor* visitor);
292 TimelineEvent* StartEvent(const Object& object); 341 TimelineEvent* StartEvent(const Object& object);
293 TimelineEvent* StartEvent(); 342 TimelineEvent* StartEvent();
294 void CompleteEvent(TimelineEvent* event); 343 void CompleteEvent(TimelineEvent* event);
295 344
296 void PrintJSONEvents(JSONArray* array) const; 345 void PrintJSONEvents(JSONArray* array) const;
297 346
298 intptr_t GetNextIndex(); 347 intptr_t GetNextIndex();
299 348
300 // events_[i] and event_objects_[i] are indexed together. 349 // events_[i] and event_objects_[i] are indexed together.
301 TimelineEvent* events_; 350 TimelineEvent* events_;
302 RawArray* event_objects_; 351 RawArray* event_objects_;
303 uintptr_t cursor_; 352 uintptr_t cursor_;
304 intptr_t capacity_; 353 intptr_t capacity_;
305 }; 354 };
306 355
307 356
308 // An abstract recorder that calls |StreamEvent| whenever an event is complete. 357 // An abstract recorder that calls |StreamEvent| whenever an event is complete.
309 // This recorder does not track Dart objects. 358 // This recorder does not track Dart objects.
310 class TimelineEventStreamingRecorder : public TimelineEventRecorder { 359 class TimelineEventStreamingRecorder : public TimelineEventRecorder {
311 public: 360 public:
312 TimelineEventStreamingRecorder(); 361 TimelineEventStreamingRecorder();
313 ~TimelineEventStreamingRecorder(); 362 ~TimelineEventStreamingRecorder();
314 363
315 void PrintJSON(JSONStream* js) const; 364 void PrintJSON(JSONStream* js);
316 365
317 // Called when |event| is ready to be streamed. It is unsafe to keep a 366 // 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. 367 // reference to |event| as it may be freed as soon as this function returns.
319 virtual void StreamEvent(TimelineEvent* event) = 0; 368 virtual void StreamEvent(TimelineEvent* event) = 0;
320 369
321 protected: 370 protected:
322 void VisitObjectPointers(ObjectPointerVisitor* visitor); 371 void VisitObjectPointers(ObjectPointerVisitor* visitor);
323 TimelineEvent* StartEvent(const Object& object); 372 TimelineEvent* StartEvent(const Object& object);
324 TimelineEvent* StartEvent(); 373 TimelineEvent* StartEvent();
325 void CompleteEvent(TimelineEvent* event); 374 void CompleteEvent(TimelineEvent* event);
326 }; 375 };
327 376
377
378 // A recorder that stores events in chains of blocks of events.
379 // This recorder does not track Dart objects.
380 // NOTE: This recorder will continue to allocate blocks until it exhausts
381 // memory.
382 class TimelineEventEndlessRecorder : public TimelineEventRecorder {
383 public:
384 TimelineEventEndlessRecorder();
385
386 // Acquire a new block of events.
387 // Takes a lock.
388 // Recorder owns the block and it should be filled by only one thread.
389 TimelineEventBlock* GetNewBlock();
390
391 // It is expected that this function is only called when an isolate is
392 // shutting itself down.
393 // NOTE: Calling this while threads are filling in their blocks is not safe
394 // and there are no checks in place to ensure that doesn't happen.
395 // TODO(koda): Add isolate count to |ThreadRegistry| and verify that it is 1.
396 void PrintJSON(JSONStream* js);
397
398 protected:
399 void VisitObjectPointers(ObjectPointerVisitor* visitor);
400 TimelineEvent* StartEvent(const Object& object);
401 TimelineEvent* StartEvent();
402 void CompleteEvent(TimelineEvent* event);
403
404 TimelineEventBlock* GetNewBlockLocked();
405 void PrintJSONEvents(JSONArray* array) const;
406
407 Mutex lock_;
408 TimelineEventBlock* head_;
409 };
410
328 } // namespace dart 411 } // namespace dart
329 412
330 #endif // VM_TIMELINE_H_ 413 #endif // VM_TIMELINE_H_
OLDNEW
« no previous file with comments | « runtime/vm/thread.h ('k') | runtime/vm/timeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698