| 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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 private: | 264 private: |
| 265 TimelineEvent* event_; | 265 TimelineEvent* event_; |
| 266 }; | 266 }; |
| 267 | 267 |
| 268 | 268 |
| 269 // A block of |TimelineEvent|s. Not thread safe. | 269 // A block of |TimelineEvent|s. Not thread safe. |
| 270 class TimelineEventBlock { | 270 class TimelineEventBlock { |
| 271 public: | 271 public: |
| 272 static const intptr_t kBlockSize = 64; | 272 static const intptr_t kBlockSize = 64; |
| 273 | 273 |
| 274 TimelineEventBlock(); | 274 explicit TimelineEventBlock(intptr_t index); |
| 275 ~TimelineEventBlock(); |
| 275 | 276 |
| 276 TimelineEventBlock* next() const { | 277 TimelineEventBlock* next() const { |
| 277 return next_; | 278 return next_; |
| 278 } | 279 } |
| 279 void set_next(TimelineEventBlock* next) { | 280 void set_next(TimelineEventBlock* next) { |
| 280 next_ = next; | 281 next_ = next; |
| 281 } | 282 } |
| 282 | 283 |
| 283 intptr_t length() const { | 284 intptr_t length() const { |
| 284 return length_; | 285 return length_; |
| 285 } | 286 } |
| 286 | 287 |
| 288 intptr_t block_index() const { |
| 289 return block_index_; |
| 290 } |
| 291 |
| 287 bool IsEmpty() const { | 292 bool IsEmpty() const { |
| 288 return length_ == 0; | 293 return length_ == 0; |
| 289 } | 294 } |
| 290 | 295 |
| 291 bool IsFull() const { | 296 bool IsFull() const { |
| 292 return length_ == kBlockSize; | 297 return length_ == kBlockSize; |
| 293 } | 298 } |
| 294 | 299 |
| 295 TimelineEvent* At(intptr_t index) { | 300 TimelineEvent* At(intptr_t index) { |
| 296 ASSERT(index >= 0); | 301 ASSERT(index >= 0); |
| 297 ASSERT(index < kBlockSize); | 302 ASSERT(index < kBlockSize); |
| 298 return &events_[index]; | 303 return &events_[index]; |
| 299 } | 304 } |
| 300 | 305 |
| 306 const TimelineEvent* At(intptr_t index) const { |
| 307 ASSERT(index >= 0); |
| 308 ASSERT(index < kBlockSize); |
| 309 return &events_[index]; |
| 310 } |
| 311 |
| 301 // Attempt to sniff a thread id from the first event. | 312 // Attempt to sniff a thread id from the first event. |
| 302 ThreadId thread() const; | 313 ThreadId thread() const; |
| 303 // Attempt to sniff the timestamp from the first event. | 314 // Attempt to sniff the timestamp from the first event. |
| 304 int64_t LowerTimeBound() const; | 315 int64_t LowerTimeBound() const; |
| 305 | 316 |
| 306 // Returns false if |this| violates any of the following invariants: | 317 // Returns false if |this| violates any of the following invariants: |
| 307 // - events in the block come from one thread. | 318 // - events in the block come from one thread. |
| 308 // - events have monotonically increasing timestamps. | 319 // - events have monotonically increasing timestamps. |
| 309 bool CheckBlock(); | 320 bool CheckBlock(); |
| 310 | 321 |
| 322 // Call Reset on all events and set length to 0. |
| 323 void Reset(); |
| 324 |
| 311 protected: | 325 protected: |
| 312 TimelineEvent* StartEvent(); | 326 TimelineEvent* StartEvent(); |
| 313 | 327 |
| 314 TimelineEvent events_[kBlockSize]; | 328 TimelineEvent events_[kBlockSize]; |
| 315 TimelineEventBlock* next_; | 329 TimelineEventBlock* next_; |
| 316 intptr_t length_; | 330 intptr_t length_; |
| 331 intptr_t block_index_; |
| 317 | 332 |
| 318 friend class TimelineEventEndlessRecorder; | 333 friend class TimelineEventEndlessRecorder; |
| 334 friend class TimelineEventRecorder; |
| 319 friend class TimelineTestHelper; | 335 friend class TimelineTestHelper; |
| 320 | 336 |
| 321 private: | 337 private: |
| 322 DISALLOW_COPY_AND_ASSIGN(TimelineEventBlock); | 338 DISALLOW_COPY_AND_ASSIGN(TimelineEventBlock); |
| 323 }; | 339 }; |
| 324 | 340 |
| 325 | 341 |
| 326 // Recorder of |TimelineEvent|s. | 342 // Recorder of |TimelineEvent|s. |
| 327 class TimelineEventRecorder { | 343 class TimelineEventRecorder { |
| 328 public: | 344 public: |
| 329 TimelineEventRecorder(); | 345 TimelineEventRecorder(); |
| 330 virtual ~TimelineEventRecorder() {} | 346 virtual ~TimelineEventRecorder() {} |
| 331 | 347 |
| 332 // Interface method(s) which must be implemented. | 348 // Interface method(s) which must be implemented. |
| 333 virtual void PrintJSON(JSONStream* js) = 0; | 349 virtual void PrintJSON(JSONStream* js) = 0; |
| 334 | 350 virtual TimelineEventBlock* GetNewBlock() = 0; |
| 335 // Override if recorder uses blocks. | |
| 336 virtual TimelineEventBlock* GetNewBlock() { | |
| 337 return NULL; | |
| 338 } | |
| 339 | 351 |
| 340 void WriteTo(const char* directory); | 352 void WriteTo(const char* directory); |
| 341 | 353 |
| 342 protected: | 354 protected: |
| 343 // Interface method(s) which must be implemented. | 355 // Interface method(s) which must be implemented. |
| 344 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor) = 0; | 356 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor) = 0; |
| 345 virtual TimelineEvent* StartEvent(const Object& object) = 0; | 357 virtual TimelineEvent* StartEvent(const Object& object) = 0; |
| 346 virtual TimelineEvent* StartEvent() = 0; | 358 virtual TimelineEvent* StartEvent() = 0; |
| 347 virtual void CompleteEvent(TimelineEvent* event) = 0; | 359 virtual void CompleteEvent(TimelineEvent* event) = 0; |
| 348 | 360 |
| 349 // Utility method(s). | 361 // Utility method(s). |
| 350 void PrintJSONMeta(JSONArray* array) const; | 362 void PrintJSONMeta(JSONArray* array) const; |
| 363 TimelineEvent* ThreadBlockStartEvent(); |
| 351 | 364 |
| 352 friend class TimelineStream; | 365 friend class TimelineStream; |
| 353 friend class Isolate; | 366 friend class Isolate; |
| 354 | 367 |
| 355 private: | 368 private: |
| 356 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); | 369 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); |
| 357 }; | 370 }; |
| 358 | 371 |
| 359 | 372 |
| 360 // A recorder that stores events in a ring buffer of fixed capacity. | 373 // A recorder that stores events in a ring buffer of fixed capacity. |
| 361 // This recorder does track Dart objects. | 374 // This recorder does track Dart objects. |
| 362 // TODO(johnmccutchan): Make this recorder use event blocks too. | |
| 363 class TimelineEventRingRecorder : public TimelineEventRecorder { | 375 class TimelineEventRingRecorder : public TimelineEventRecorder { |
| 364 public: | 376 public: |
| 365 static const intptr_t kDefaultCapacity = 8192; | 377 static const intptr_t kDefaultCapacity = 8192; |
| 366 | 378 |
| 367 static intptr_t SizeForCapacity(intptr_t capacity); | |
| 368 | |
| 369 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); | 379 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); |
| 370 ~TimelineEventRingRecorder(); | 380 ~TimelineEventRingRecorder(); |
| 371 | 381 |
| 372 void PrintJSON(JSONStream* js); | 382 void PrintJSON(JSONStream* js); |
| 383 TimelineEventBlock* GetNewBlock(); |
| 373 | 384 |
| 374 protected: | 385 protected: |
| 375 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 386 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 376 TimelineEvent* StartEvent(const Object& object); | 387 TimelineEvent* StartEvent(const Object& object); |
| 377 TimelineEvent* StartEvent(); | 388 TimelineEvent* StartEvent(); |
| 378 void CompleteEvent(TimelineEvent* event); | 389 void CompleteEvent(TimelineEvent* event); |
| 379 | 390 |
| 391 TimelineEventBlock* GetNewBlockLocked(); |
| 392 |
| 380 void PrintJSONEvents(JSONArray* array) const; | 393 void PrintJSONEvents(JSONArray* array) const; |
| 381 | 394 |
| 382 intptr_t GetNextIndex(); | 395 TimelineEventBlock** blocks_; |
| 383 | |
| 384 // events_[i] and event_objects_[i] are indexed together. | |
| 385 TimelineEvent* events_; | |
| 386 RawArray* event_objects_; | 396 RawArray* event_objects_; |
| 387 uintptr_t cursor_; | |
| 388 intptr_t capacity_; | 397 intptr_t capacity_; |
| 398 intptr_t num_blocks_; |
| 399 intptr_t block_cursor_; |
| 400 Mutex lock_; |
| 389 }; | 401 }; |
| 390 | 402 |
| 391 | 403 |
| 392 // An abstract recorder that calls |StreamEvent| whenever an event is complete. | 404 // An abstract recorder that calls |StreamEvent| whenever an event is complete. |
| 393 // This recorder does not track Dart objects. | 405 // This recorder does not track Dart objects. |
| 394 class TimelineEventStreamingRecorder : public TimelineEventRecorder { | 406 class TimelineEventStreamingRecorder : public TimelineEventRecorder { |
| 395 public: | 407 public: |
| 396 TimelineEventStreamingRecorder(); | 408 TimelineEventStreamingRecorder(); |
| 397 ~TimelineEventStreamingRecorder(); | 409 ~TimelineEventStreamingRecorder(); |
| 398 | 410 |
| 399 void PrintJSON(JSONStream* js); | 411 void PrintJSON(JSONStream* js); |
| 412 virtual TimelineEventBlock* GetNewBlock() { |
| 413 return NULL; |
| 414 } |
| 400 | 415 |
| 401 // Called when |event| is ready to be streamed. It is unsafe to keep a | 416 // Called when |event| is ready to be streamed. It is unsafe to keep a |
| 402 // reference to |event| as it may be freed as soon as this function returns. | 417 // reference to |event| as it may be freed as soon as this function returns. |
| 403 virtual void StreamEvent(TimelineEvent* event) = 0; | 418 virtual void StreamEvent(TimelineEvent* event) = 0; |
| 404 | 419 |
| 405 protected: | 420 protected: |
| 406 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 421 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 407 TimelineEvent* StartEvent(const Object& object); | 422 TimelineEvent* StartEvent(const Object& object); |
| 408 TimelineEvent* StartEvent(); | 423 TimelineEvent* StartEvent(); |
| 409 void CompleteEvent(TimelineEvent* event); | 424 void CompleteEvent(TimelineEvent* event); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 434 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 449 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 435 TimelineEvent* StartEvent(const Object& object); | 450 TimelineEvent* StartEvent(const Object& object); |
| 436 TimelineEvent* StartEvent(); | 451 TimelineEvent* StartEvent(); |
| 437 void CompleteEvent(TimelineEvent* event); | 452 void CompleteEvent(TimelineEvent* event); |
| 438 | 453 |
| 439 TimelineEventBlock* GetNewBlockLocked(); | 454 TimelineEventBlock* GetNewBlockLocked(); |
| 440 void PrintJSONEvents(JSONArray* array) const; | 455 void PrintJSONEvents(JSONArray* array) const; |
| 441 | 456 |
| 442 Mutex lock_; | 457 Mutex lock_; |
| 443 TimelineEventBlock* head_; | 458 TimelineEventBlock* head_; |
| 459 intptr_t block_index_; |
| 444 | 460 |
| 445 friend class TimelineEventBlockIterator; | 461 friend class TimelineEventBlockIterator; |
| 446 }; | 462 }; |
| 447 | 463 |
| 448 | 464 |
| 449 // An iterator for blocks. | 465 // An iterator for blocks. |
| 450 class TimelineEventBlockIterator { | 466 class TimelineEventBlockIterator { |
| 451 public: | 467 public: |
| 452 explicit TimelineEventBlockIterator(TimelineEventEndlessRecorder* recorder); | 468 explicit TimelineEventBlockIterator(TimelineEventEndlessRecorder* recorder); |
| 453 ~TimelineEventBlockIterator(); | 469 ~TimelineEventBlockIterator(); |
| 454 | 470 |
| 455 void Reset(); | 471 void Reset(); |
| 456 bool Next(); | 472 bool Next(); |
| 457 | 473 |
| 458 TimelineEventBlock* current() const { | 474 TimelineEventBlock* current() const { |
| 459 return current_; | 475 return current_; |
| 460 } | 476 } |
| 461 | 477 |
| 462 private: | 478 private: |
| 463 TimelineEventBlock* current_; | 479 TimelineEventBlock* current_; |
| 464 TimelineEventEndlessRecorder* recorder_; | 480 TimelineEventEndlessRecorder* recorder_; |
| 465 }; | 481 }; |
| 466 | 482 |
| 467 } // namespace dart | 483 } // namespace dart |
| 468 | 484 |
| 469 #endif // VM_TIMELINE_H_ | 485 #endif // VM_TIMELINE_H_ |
| OLD | NEW |