| 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 |