OLD | NEW |
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/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/bitfield.h" | 9 #include "vm/bitfield.h" |
10 | 10 |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 | 341 |
342 // Recorder of |TimelineEvent|s. | 342 // Recorder of |TimelineEvent|s. |
343 class TimelineEventRecorder { | 343 class TimelineEventRecorder { |
344 public: | 344 public: |
345 TimelineEventRecorder(); | 345 TimelineEventRecorder(); |
346 virtual ~TimelineEventRecorder() {} | 346 virtual ~TimelineEventRecorder() {} |
347 | 347 |
348 // Interface method(s) which must be implemented. | 348 // Interface method(s) which must be implemented. |
349 virtual void PrintJSON(JSONStream* js) = 0; | 349 virtual void PrintJSON(JSONStream* js) = 0; |
350 virtual TimelineEventBlock* GetNewBlock() = 0; | 350 virtual TimelineEventBlock* GetNewBlock() = 0; |
| 351 virtual TimelineEventBlock* GetHeadBlock() = 0; |
351 | 352 |
352 void WriteTo(const char* directory); | 353 void WriteTo(const char* directory); |
353 | 354 |
354 protected: | 355 protected: |
355 // Interface method(s) which must be implemented. | 356 // Interface method(s) which must be implemented. |
356 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor) = 0; | 357 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor) = 0; |
357 virtual TimelineEvent* StartEvent(const Object& object) = 0; | 358 virtual TimelineEvent* StartEvent(const Object& object) = 0; |
358 virtual TimelineEvent* StartEvent() = 0; | 359 virtual TimelineEvent* StartEvent() = 0; |
359 virtual void CompleteEvent(TimelineEvent* event) = 0; | 360 virtual void CompleteEvent(TimelineEvent* event) = 0; |
360 | 361 |
361 // Utility method(s). | 362 // Utility method(s). |
362 void PrintJSONMeta(JSONArray* array) const; | 363 void PrintJSONMeta(JSONArray* array) const; |
363 TimelineEvent* ThreadBlockStartEvent(); | 364 TimelineEvent* ThreadBlockStartEvent(); |
364 | 365 |
| 366 Mutex lock_; |
| 367 |
| 368 friend class TimelineEventBlockIterator; |
365 friend class TimelineStream; | 369 friend class TimelineStream; |
366 friend class Isolate; | 370 friend class Isolate; |
367 | 371 |
368 private: | 372 private: |
369 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); | 373 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); |
370 }; | 374 }; |
371 | 375 |
372 | 376 |
373 // A recorder that stores events in a ring buffer of fixed capacity. | 377 // A recorder that stores events in a ring buffer of fixed capacity. |
374 // This recorder does track Dart objects. | 378 // This recorder does track Dart objects. |
375 class TimelineEventRingRecorder : public TimelineEventRecorder { | 379 class TimelineEventRingRecorder : public TimelineEventRecorder { |
376 public: | 380 public: |
377 static const intptr_t kDefaultCapacity = 8192; | 381 static const intptr_t kDefaultCapacity = 8192; |
378 | 382 |
379 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); | 383 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); |
380 ~TimelineEventRingRecorder(); | 384 ~TimelineEventRingRecorder(); |
381 | 385 |
382 void PrintJSON(JSONStream* js); | 386 void PrintJSON(JSONStream* js); |
383 TimelineEventBlock* GetNewBlock(); | 387 TimelineEventBlock* GetNewBlock(); |
| 388 TimelineEventBlock* GetHeadBlock(); |
384 | 389 |
385 protected: | 390 protected: |
386 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 391 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
387 TimelineEvent* StartEvent(const Object& object); | 392 TimelineEvent* StartEvent(const Object& object); |
388 TimelineEvent* StartEvent(); | 393 TimelineEvent* StartEvent(); |
389 void CompleteEvent(TimelineEvent* event); | 394 void CompleteEvent(TimelineEvent* event); |
390 | 395 |
391 TimelineEventBlock* GetNewBlockLocked(); | 396 TimelineEventBlock* GetNewBlockLocked(); |
392 | 397 |
393 void PrintJSONEvents(JSONArray* array) const; | 398 void PrintJSONEvents(JSONArray* array) const; |
394 | 399 |
395 TimelineEventBlock** blocks_; | 400 TimelineEventBlock** blocks_; |
396 RawArray* event_objects_; | 401 RawArray* event_objects_; |
397 intptr_t capacity_; | 402 intptr_t capacity_; |
398 intptr_t num_blocks_; | 403 intptr_t num_blocks_; |
399 intptr_t block_cursor_; | 404 intptr_t block_cursor_; |
400 Mutex lock_; | |
401 }; | 405 }; |
402 | 406 |
403 | 407 |
404 // An abstract recorder that calls |StreamEvent| whenever an event is complete. | 408 // An abstract recorder that calls |StreamEvent| whenever an event is complete. |
405 // This recorder does not track Dart objects. | 409 // This recorder does not track Dart objects. |
406 class TimelineEventStreamingRecorder : public TimelineEventRecorder { | 410 class TimelineEventStreamingRecorder : public TimelineEventRecorder { |
407 public: | 411 public: |
408 TimelineEventStreamingRecorder(); | 412 TimelineEventStreamingRecorder(); |
409 ~TimelineEventStreamingRecorder(); | 413 ~TimelineEventStreamingRecorder(); |
410 | 414 |
411 void PrintJSON(JSONStream* js); | 415 void PrintJSON(JSONStream* js); |
412 virtual TimelineEventBlock* GetNewBlock() { | 416 TimelineEventBlock* GetNewBlock() { |
| 417 return NULL; |
| 418 } |
| 419 TimelineEventBlock* GetHeadBlock() { |
413 return NULL; | 420 return NULL; |
414 } | 421 } |
415 | 422 |
416 // Called when |event| is ready to be streamed. It is unsafe to keep a | 423 // Called when |event| is ready to be streamed. It is unsafe to keep a |
417 // reference to |event| as it may be freed as soon as this function returns. | 424 // reference to |event| as it may be freed as soon as this function returns. |
418 virtual void StreamEvent(TimelineEvent* event) = 0; | 425 virtual void StreamEvent(TimelineEvent* event) = 0; |
419 | 426 |
420 protected: | 427 protected: |
421 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 428 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
422 TimelineEvent* StartEvent(const Object& object); | 429 TimelineEvent* StartEvent(const Object& object); |
423 TimelineEvent* StartEvent(); | 430 TimelineEvent* StartEvent(); |
424 void CompleteEvent(TimelineEvent* event); | 431 void CompleteEvent(TimelineEvent* event); |
425 }; | 432 }; |
426 | 433 |
427 | 434 |
428 // A recorder that stores events in chains of blocks of events. | 435 // A recorder that stores events in chains of blocks of events. |
429 // This recorder does not track Dart objects. | 436 // This recorder does not track Dart objects. |
430 // NOTE: This recorder will continue to allocate blocks until it exhausts | 437 // NOTE: This recorder will continue to allocate blocks until it exhausts |
431 // memory. | 438 // memory. |
432 class TimelineEventEndlessRecorder : public TimelineEventRecorder { | 439 class TimelineEventEndlessRecorder : public TimelineEventRecorder { |
433 public: | 440 public: |
434 TimelineEventEndlessRecorder(); | 441 TimelineEventEndlessRecorder(); |
435 | 442 |
436 // Acquire a new block of events. | 443 // Acquire a new block of events. |
437 // Takes a lock. | 444 // Takes a lock. |
438 // Recorder owns the block and it should be filled by only one thread. | 445 // Recorder owns the block and it should be filled by only one thread. |
439 TimelineEventBlock* GetNewBlock(); | 446 TimelineEventBlock* GetNewBlock(); |
440 | 447 |
| 448 TimelineEventBlock* GetHeadBlock(); |
| 449 |
441 // It is expected that this function is only called when an isolate is | 450 // It is expected that this function is only called when an isolate is |
442 // shutting itself down. | 451 // shutting itself down. |
443 // NOTE: Calling this while threads are filling in their blocks is not safe | 452 // NOTE: Calling this while threads are filling in their blocks is not safe |
444 // and there are no checks in place to ensure that doesn't happen. | 453 // and there are no checks in place to ensure that doesn't happen. |
445 // TODO(koda): Add isolate count to |ThreadRegistry| and verify that it is 1. | 454 // TODO(koda): Add isolate count to |ThreadRegistry| and verify that it is 1. |
446 void PrintJSON(JSONStream* js); | 455 void PrintJSON(JSONStream* js); |
447 | 456 |
448 protected: | 457 protected: |
449 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 458 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
450 TimelineEvent* StartEvent(const Object& object); | 459 TimelineEvent* StartEvent(const Object& object); |
451 TimelineEvent* StartEvent(); | 460 TimelineEvent* StartEvent(); |
452 void CompleteEvent(TimelineEvent* event); | 461 void CompleteEvent(TimelineEvent* event); |
453 | 462 |
454 TimelineEventBlock* GetNewBlockLocked(); | 463 TimelineEventBlock* GetNewBlockLocked(); |
455 void PrintJSONEvents(JSONArray* array) const; | 464 void PrintJSONEvents(JSONArray* array) const; |
456 | 465 |
457 Mutex lock_; | |
458 TimelineEventBlock* head_; | 466 TimelineEventBlock* head_; |
459 intptr_t block_index_; | 467 intptr_t block_index_; |
460 | |
461 friend class TimelineEventBlockIterator; | |
462 }; | 468 }; |
463 | 469 |
464 | 470 |
465 // An iterator for blocks. | 471 // An iterator for blocks. |
466 class TimelineEventBlockIterator { | 472 class TimelineEventBlockIterator { |
467 public: | 473 public: |
468 explicit TimelineEventBlockIterator(TimelineEventEndlessRecorder* recorder); | 474 explicit TimelineEventBlockIterator(TimelineEventRecorder* recorder); |
469 ~TimelineEventBlockIterator(); | 475 ~TimelineEventBlockIterator(); |
470 | 476 |
471 void Reset(); | 477 void Reset(); |
472 bool Next(); | 478 bool Next(); |
473 | 479 |
474 TimelineEventBlock* current() const { | 480 TimelineEventBlock* current() const { |
475 return current_; | 481 return current_; |
476 } | 482 } |
477 | 483 |
478 private: | 484 private: |
479 TimelineEventBlock* current_; | 485 TimelineEventBlock* current_; |
480 TimelineEventEndlessRecorder* recorder_; | 486 TimelineEventRecorder* recorder_; |
481 }; | 487 }; |
482 | 488 |
483 } // namespace dart | 489 } // namespace dart |
484 | 490 |
485 #endif // VM_TIMELINE_H_ | 491 #endif // VM_TIMELINE_H_ |
OLD | NEW |