| 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 |
| 11 namespace dart { | 11 namespace dart { |
| 12 | 12 |
| 13 class JSONArray; | 13 class JSONArray; |
| 14 class JSONObject; | 14 class JSONObject; |
| 15 class JSONStream; | 15 class JSONStream; |
| 16 class Object; | 16 class Object; |
| 17 class ObjectPointerVisitor; | 17 class ObjectPointerVisitor; |
| 18 class RawArray; | 18 class RawArray; |
| 19 class Thread; | 19 class Thread; |
| 20 class TimelineEvent; | 20 class TimelineEvent; |
| 21 class TimelineEventBlock; | 21 class TimelineEventBlock; |
| 22 class TimelineEventRecorder; | 22 class TimelineEventRecorder; |
| 23 class TimelineStream; | 23 class TimelineStream; |
| 24 | 24 |
| 25 |
| 26 class Timeline : public AllStatic { |
| 27 public: |
| 28 // Initialize timeline system. Not thread safe. |
| 29 static void InitOnce(); |
| 30 |
| 31 // Shutdown timeline system. Not thread safe. |
| 32 static void Shutdown(); |
| 33 |
| 34 // Access the global recorder. Not thread safe. |
| 35 static TimelineEventRecorder* recorder(); |
| 36 |
| 37 static bool EnableStreamByDefault(const char* stream_name); |
| 38 |
| 39 static TimelineStream* GetVMStream(); |
| 40 |
| 41 private: |
| 42 static TimelineEventRecorder* recorder_; |
| 43 static TimelineStream* vm_stream_; |
| 44 |
| 45 friend class TimelineRecorderOverride; |
| 46 }; |
| 47 |
| 48 |
| 25 // You should get a |TimelineEvent| from a |TimelineStream|. | 49 // You should get a |TimelineEvent| from a |TimelineStream|. |
| 26 class TimelineEvent { | 50 class TimelineEvent { |
| 27 public: | 51 public: |
| 28 // Keep in sync with StateBits below. | 52 // Keep in sync with StateBits below. |
| 29 enum EventType { | 53 enum EventType { |
| 30 kNone, | 54 kNone, |
| 31 kDuration, | 55 kDuration, |
| 32 kInstant, | 56 kInstant, |
| 33 kAsyncBegin, | 57 kAsyncBegin, |
| 34 kAsyncInstant, | 58 kAsyncInstant, |
| 35 kAsyncEnd, | 59 kAsyncEnd, |
| 36 kNumEventTypes, | 60 kNumEventTypes, |
| 37 }; | 61 }; |
| 38 | 62 |
| 39 TimelineEvent(); | 63 TimelineEvent(); |
| 40 ~TimelineEvent(); | 64 ~TimelineEvent(); |
| 41 | 65 |
| 42 void Reset(); | 66 void Reset(); |
| 43 | 67 |
| 44 bool IsValid() const { | 68 bool IsValid() const { |
| 45 return (event_type() > kNone) && (event_type() < kNumEventTypes); | 69 return (event_type() > kNone) && (event_type() < kNumEventTypes); |
| 46 } | 70 } |
| 47 | 71 |
| 48 // Marks the beginning of an asynchronous operation. | 72 // Marks the beginning of an asynchronous operation with |async_id|. |
| 49 // Returns |async_id| which must be passed to |AsyncInstant| and |AsyncEnd|. | 73 void AsyncBegin(const char* label, int64_t async_id); |
| 50 int64_t AsyncBegin(const char* label); | |
| 51 // Marks an instantaneous event associated with |async_id|. | 74 // Marks an instantaneous event associated with |async_id|. |
| 52 void AsyncInstant(const char* label, | 75 void AsyncInstant(const char* label, |
| 53 int64_t async_id); | 76 int64_t async_id); |
| 54 // Marks the end of an asynchronous operation associated with |async_id|. | 77 // Marks the end of an asynchronous operation associated with |async_id|. |
| 55 void AsyncEnd(const char* label, | 78 void AsyncEnd(const char* label, |
| 56 int64_t async_id); | 79 int64_t async_id); |
| 57 | 80 |
| 58 void DurationBegin(const char* label); | 81 void DurationBegin(const char* label); |
| 59 void DurationEnd(); | 82 void DurationEnd(); |
| 60 void Instant(const char* label); | 83 void Instant(const char* label); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 const char* name; | 155 const char* name; |
| 133 char* value; | 156 char* value; |
| 134 }; | 157 }; |
| 135 | 158 |
| 136 int64_t timestamp0_; | 159 int64_t timestamp0_; |
| 137 int64_t timestamp1_; | 160 int64_t timestamp1_; |
| 138 TimelineEventArgument* arguments_; | 161 TimelineEventArgument* arguments_; |
| 139 intptr_t arguments_length_; | 162 intptr_t arguments_length_; |
| 140 uword state_; | 163 uword state_; |
| 141 const char* label_; | 164 const char* label_; |
| 142 TimelineStream* stream_; | 165 const char* category_; |
| 143 ThreadId thread_; | 166 ThreadId thread_; |
| 167 Isolate* isolate_; |
| 144 | 168 |
| 145 void FreeArguments(); | 169 void FreeArguments(); |
| 146 | 170 |
| 147 void StreamInit(TimelineStream* stream); | 171 void StreamInit(TimelineStream* stream); |
| 148 void Init(EventType event_type, const char* label); | 172 void Init(EventType event_type, const char* label); |
| 149 | 173 |
| 150 void set_event_type(EventType event_type) { | 174 void set_event_type(EventType event_type) { |
| 151 state_ = EventTypeField::update(event_type, state_); | 175 state_ = EventTypeField::update(event_type, state_); |
| 152 } | 176 } |
| 153 | 177 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 178 } | 202 } |
| 179 | 203 |
| 180 bool enabled() const { | 204 bool enabled() const { |
| 181 return enabled_; | 205 return enabled_; |
| 182 } | 206 } |
| 183 | 207 |
| 184 void set_enabled(bool enabled) { | 208 void set_enabled(bool enabled) { |
| 185 enabled_ = enabled; | 209 enabled_ = enabled; |
| 186 } | 210 } |
| 187 | 211 |
| 188 TimelineEventRecorder* recorder() const { | |
| 189 return recorder_; | |
| 190 } | |
| 191 | |
| 192 // TODO(johnmccutchan): Disallow setting recorder after Init? | |
| 193 void set_recorder(TimelineEventRecorder* recorder) { | |
| 194 recorder_ = recorder; | |
| 195 } | |
| 196 | |
| 197 // Records an event. Will return |NULL| if not enabled. The returned | 212 // Records an event. Will return |NULL| if not enabled. The returned |
| 198 // |TimelineEvent| is in an undefined state and must be initialized. | 213 // |TimelineEvent| is in an undefined state and must be initialized. |
| 199 TimelineEvent* StartEvent(); | 214 TimelineEvent* StartEvent(); |
| 200 | 215 |
| 201 void CompleteEvent(TimelineEvent* event); | |
| 202 | |
| 203 int64_t GetNextSeq(); | |
| 204 | |
| 205 private: | 216 private: |
| 206 TimelineEventRecorder* recorder_; | |
| 207 const char* name_; | 217 const char* name_; |
| 208 bool enabled_; | 218 bool enabled_; |
| 209 int64_t seq_; | |
| 210 }; | 219 }; |
| 211 | 220 |
| 212 | 221 |
| 213 // (name, enabled by default). | 222 // (name, enabled by default). |
| 214 #define ISOLATE_TIMELINE_STREAM_LIST(V) \ | 223 #define ISOLATE_TIMELINE_STREAM_LIST(V) \ |
| 215 V(API, false) \ | 224 V(API, false) \ |
| 216 V(Compiler, false) \ | 225 V(Compiler, false) \ |
| 217 V(Embedder, false) \ | 226 V(Embedder, false) \ |
| 218 V(GC, false) \ | 227 V(GC, false) \ |
| 219 V(Isolate, false) \ | 228 V(Isolate, false) \ |
| 220 | 229 |
| 221 | 230 |
| 222 #define TIMELINE_FUNCTION_COMPILATION_DURATION(isolate, suffix, function) \ | 231 #define TIMELINE_FUNCTION_COMPILATION_DURATION(isolate, suffix, function) \ |
| 223 TimelineDurationScope tds(isolate, \ | 232 TimelineDurationScope tds(isolate, \ |
| 224 isolate->GetCompilerStream(), \ | 233 isolate->GetCompilerStream(), \ |
| 225 "Compile" suffix); \ | 234 "Compile" suffix); \ |
| 226 if (tds.enabled()) { \ | 235 if (tds.enabled()) { \ |
| 227 tds.SetNumArguments(1); \ | 236 tds.SetNumArguments(1); \ |
| 228 tds.CopyArgument( \ | 237 tds.CopyArgument( \ |
| 229 0, \ | 238 0, \ |
| 230 "function", \ | 239 "function", \ |
| 231 const_cast<char*>(function.QualifiedUserVisibleNameCString())); \ | 240 const_cast<char*>(function.ToLibNamePrefixedQualifiedCString())); \ |
| 232 } | 241 } |
| 233 | 242 |
| 243 |
| 244 // TODO(johnmccutchan): TimelineDurationScope should only allocate the |
| 245 // event when complete. |
| 234 class TimelineDurationScope : public StackResource { | 246 class TimelineDurationScope : public StackResource { |
| 235 public: | 247 public: |
| 236 TimelineDurationScope(Isolate* isolate, | 248 TimelineDurationScope(Isolate* isolate, |
| 237 TimelineStream* stream, | 249 TimelineStream* stream, |
| 238 const char* label) | 250 const char* label) |
| 239 : StackResource(isolate) { | 251 : StackResource(isolate) { |
| 240 Init(stream, label); | 252 Init(stream, label); |
| 241 } | 253 } |
| 242 | 254 |
| 243 TimelineDurationScope(Thread* thread, | 255 TimelineDurationScope(Thread* thread, |
| 244 TimelineStream* stream, | 256 TimelineStream* stream, |
| 245 const char* label) | 257 const char* label) |
| 246 : StackResource(thread) { | 258 : StackResource(thread) { |
| 247 Init(stream, label); | 259 Init(stream, label); |
| 248 } | 260 } |
| 249 | 261 |
| 262 TimelineDurationScope(TimelineStream* stream, |
| 263 const char* label) |
| 264 : StackResource(reinterpret_cast<Thread*>(NULL)) { |
| 265 Init(stream, label); |
| 266 } |
| 267 |
| 250 void Init(TimelineStream* stream, const char* label) { | 268 void Init(TimelineStream* stream, const char* label) { |
| 251 event_ = stream->StartEvent(); | 269 event_ = stream->StartEvent(); |
| 252 if (event_ == NULL) { | 270 if (event_ == NULL) { |
| 253 return; | 271 return; |
| 254 } | 272 } |
| 255 event_->DurationBegin(label); | 273 event_->DurationBegin(label); |
| 256 } | 274 } |
| 257 | 275 |
| 258 bool enabled() const { | 276 bool enabled() const { |
| 259 return event_ != NULL; | 277 return event_ != NULL; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 int64_t LowerTimeBound() const; | 364 int64_t LowerTimeBound() const; |
| 347 | 365 |
| 348 // Returns false if |this| violates any of the following invariants: | 366 // Returns false if |this| violates any of the following invariants: |
| 349 // - events in the block come from one thread. | 367 // - events in the block come from one thread. |
| 350 // - events have monotonically increasing timestamps. | 368 // - events have monotonically increasing timestamps. |
| 351 bool CheckBlock(); | 369 bool CheckBlock(); |
| 352 | 370 |
| 353 // Call Reset on all events and set length to 0. | 371 // Call Reset on all events and set length to 0. |
| 354 void Reset(); | 372 void Reset(); |
| 355 | 373 |
| 374 // Only safe to access under the recorder's lock. |
| 375 bool open() const { |
| 376 return open_; |
| 377 } |
| 378 |
| 379 // Only safe to access under the recorder's lock. |
| 380 Isolate* isolate() const { |
| 381 return isolate_; |
| 382 } |
| 383 |
| 356 protected: | 384 protected: |
| 357 TimelineEvent* StartEvent(); | 385 TimelineEvent* StartEvent(); |
| 358 | 386 |
| 359 TimelineEvent events_[kBlockSize]; | 387 TimelineEvent events_[kBlockSize]; |
| 360 TimelineEventBlock* next_; | 388 TimelineEventBlock* next_; |
| 361 intptr_t length_; | 389 intptr_t length_; |
| 362 intptr_t block_index_; | 390 intptr_t block_index_; |
| 363 | 391 |
| 392 // Only accessed under the recorder's lock. |
| 393 Isolate* isolate_; |
| 394 bool open_; |
| 395 |
| 396 void Open(Isolate* isolate); |
| 397 void Finish(); |
| 398 |
| 399 friend class ThreadRegistry; |
| 400 friend class TimelineEventRecorder; |
| 401 friend class TimelineEventRingRecorder; |
| 364 friend class TimelineEventEndlessRecorder; | 402 friend class TimelineEventEndlessRecorder; |
| 365 friend class TimelineEventRecorder; | |
| 366 friend class TimelineTestHelper; | 403 friend class TimelineTestHelper; |
| 367 | 404 |
| 368 private: | 405 private: |
| 369 DISALLOW_COPY_AND_ASSIGN(TimelineEventBlock); | 406 DISALLOW_COPY_AND_ASSIGN(TimelineEventBlock); |
| 370 }; | 407 }; |
| 371 | 408 |
| 372 | 409 |
| 410 class TimelineEventFilter : public ValueObject { |
| 411 public: |
| 412 TimelineEventFilter(); |
| 413 virtual ~TimelineEventFilter(); |
| 414 |
| 415 virtual bool IncludeBlock(TimelineEventBlock* block) { |
| 416 if (block == NULL) { |
| 417 return false; |
| 418 } |
| 419 // Not empty and not open. |
| 420 return !block->IsEmpty() && !block->open(); |
| 421 } |
| 422 |
| 423 virtual bool IncludeEvent(TimelineEvent* event) { |
| 424 if (event == NULL) { |
| 425 return false; |
| 426 } |
| 427 return event->IsValid(); |
| 428 } |
| 429 |
| 430 private: |
| 431 }; |
| 432 |
| 433 |
| 434 class IsolateTimelineEventFilter : public TimelineEventFilter { |
| 435 public: |
| 436 explicit IsolateTimelineEventFilter(Isolate* isolate); |
| 437 |
| 438 bool IncludeBlock(TimelineEventBlock* block) { |
| 439 if (block == NULL) { |
| 440 return false; |
| 441 } |
| 442 // Not empty, not open, and isolate match. |
| 443 return !block->IsEmpty() && |
| 444 (block->isolate() == isolate_); |
| 445 } |
| 446 |
| 447 private: |
| 448 Isolate* isolate_; |
| 449 }; |
| 450 |
| 451 |
| 373 // Recorder of |TimelineEvent|s. | 452 // Recorder of |TimelineEvent|s. |
| 374 class TimelineEventRecorder { | 453 class TimelineEventRecorder { |
| 375 public: | 454 public: |
| 376 TimelineEventRecorder(); | 455 TimelineEventRecorder(); |
| 377 virtual ~TimelineEventRecorder() {} | 456 virtual ~TimelineEventRecorder() {} |
| 378 | 457 |
| 458 TimelineEventBlock* GetNewBlock(); |
| 459 |
| 379 // Interface method(s) which must be implemented. | 460 // Interface method(s) which must be implemented. |
| 380 virtual void PrintJSON(JSONStream* js) = 0; | 461 virtual void PrintJSON(JSONStream* js, TimelineEventFilter* filter) = 0; |
| 381 virtual TimelineEventBlock* GetNewBlock() = 0; | |
| 382 virtual TimelineEventBlock* GetHeadBlock() = 0; | |
| 383 | 462 |
| 463 int64_t GetNextAsyncId(); |
| 464 |
| 465 protected: |
| 384 void WriteTo(const char* directory); | 466 void WriteTo(const char* directory); |
| 385 | 467 |
| 386 protected: | |
| 387 // Interface method(s) which must be implemented. | 468 // Interface method(s) which must be implemented. |
| 388 virtual TimelineEvent* StartEvent() = 0; | 469 virtual TimelineEvent* StartEvent() = 0; |
| 389 virtual void CompleteEvent(TimelineEvent* event) = 0; | 470 virtual void CompleteEvent(TimelineEvent* event) = 0; |
| 471 virtual TimelineEventBlock* GetHeadBlockLocked() = 0; |
| 472 virtual TimelineEventBlock* GetNewBlockLocked(Isolate* isolate) = 0; |
| 390 | 473 |
| 391 // Utility method(s). | 474 // Utility method(s). |
| 392 void PrintJSONMeta(JSONArray* array) const; | 475 void PrintJSONMeta(JSONArray* array) const; |
| 393 TimelineEvent* ThreadBlockStartEvent(); | 476 TimelineEvent* ThreadBlockStartEvent(); |
| 477 TimelineEvent* GlobalBlockStartEvent(); |
| 394 | 478 |
| 395 Mutex lock_; | 479 Mutex lock_; |
| 480 // Only accessed under |lock_|. |
| 481 TimelineEventBlock* global_block_; |
| 482 void FinishGlobalBlock(); |
| 396 | 483 |
| 484 uintptr_t async_id_; |
| 485 |
| 486 friend class ThreadRegistry; |
| 487 friend class TimelineEvent; |
| 397 friend class TimelineEventBlockIterator; | 488 friend class TimelineEventBlockIterator; |
| 398 friend class TimelineStream; | 489 friend class TimelineStream; |
| 399 friend class TimelineTestHelper; | 490 friend class TimelineTestHelper; |
| 491 friend class Timeline; |
| 400 friend class Isolate; | 492 friend class Isolate; |
| 401 | 493 |
| 402 private: | 494 private: |
| 403 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); | 495 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); |
| 404 }; | 496 }; |
| 405 | 497 |
| 406 | 498 |
| 407 // A recorder that stores events in a ring buffer of fixed capacity. | 499 // A recorder that stores events in a ring buffer of fixed capacity. |
| 408 class TimelineEventRingRecorder : public TimelineEventRecorder { | 500 class TimelineEventRingRecorder : public TimelineEventRecorder { |
| 409 public: | 501 public: |
| 410 static const intptr_t kDefaultCapacity = 8192; | 502 static const intptr_t kDefaultCapacity = 8192; |
| 411 | 503 |
| 412 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); | 504 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); |
| 413 ~TimelineEventRingRecorder(); | 505 ~TimelineEventRingRecorder(); |
| 414 | 506 |
| 415 void PrintJSON(JSONStream* js); | 507 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); |
| 416 TimelineEventBlock* GetNewBlock(); | |
| 417 TimelineEventBlock* GetHeadBlock(); | |
| 418 | 508 |
| 419 protected: | 509 protected: |
| 420 TimelineEvent* StartEvent(); | 510 TimelineEvent* StartEvent(); |
| 421 void CompleteEvent(TimelineEvent* event); | 511 void CompleteEvent(TimelineEvent* event); |
| 512 TimelineEventBlock* GetHeadBlockLocked(); |
| 513 intptr_t FindOldestBlockIndex() const; |
| 514 TimelineEventBlock* GetNewBlockLocked(Isolate* isolate); |
| 422 | 515 |
| 423 intptr_t FindOldestBlockIndex() const; | 516 void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter) const; |
| 424 TimelineEventBlock* GetNewBlockLocked(); | |
| 425 | |
| 426 void PrintJSONEvents(JSONArray* array) const; | |
| 427 | 517 |
| 428 TimelineEventBlock** blocks_; | 518 TimelineEventBlock** blocks_; |
| 429 RawArray* event_objects_; | |
| 430 intptr_t capacity_; | 519 intptr_t capacity_; |
| 431 intptr_t num_blocks_; | 520 intptr_t num_blocks_; |
| 432 intptr_t block_cursor_; | 521 intptr_t block_cursor_; |
| 433 }; | 522 }; |
| 434 | 523 |
| 435 | 524 |
| 436 // An abstract recorder that calls |StreamEvent| whenever an event is complete. | 525 // An abstract recorder that calls |StreamEvent| whenever an event is complete. |
| 437 class TimelineEventStreamingRecorder : public TimelineEventRecorder { | 526 class TimelineEventStreamingRecorder : public TimelineEventRecorder { |
| 438 public: | 527 public: |
| 439 TimelineEventStreamingRecorder(); | 528 TimelineEventStreamingRecorder(); |
| 440 ~TimelineEventStreamingRecorder(); | 529 ~TimelineEventStreamingRecorder(); |
| 441 | 530 |
| 442 void PrintJSON(JSONStream* js); | 531 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); |
| 443 TimelineEventBlock* GetNewBlock() { | |
| 444 return NULL; | |
| 445 } | |
| 446 TimelineEventBlock* GetHeadBlock() { | |
| 447 return NULL; | |
| 448 } | |
| 449 | 532 |
| 450 // Called when |event| is ready to be streamed. It is unsafe to keep a | 533 // Called when |event| is ready to be streamed. It is unsafe to keep a |
| 451 // reference to |event| as it may be freed as soon as this function returns. | 534 // reference to |event| as it may be freed as soon as this function returns. |
| 452 virtual void StreamEvent(TimelineEvent* event) = 0; | 535 virtual void StreamEvent(TimelineEvent* event) = 0; |
| 453 | 536 |
| 454 protected: | 537 protected: |
| 538 TimelineEventBlock* GetNewBlockLocked(Isolate* isolate) { |
| 539 return NULL; |
| 540 } |
| 541 TimelineEventBlock* GetHeadBlockLocked() { |
| 542 return NULL; |
| 543 } |
| 455 TimelineEvent* StartEvent(); | 544 TimelineEvent* StartEvent(); |
| 456 void CompleteEvent(TimelineEvent* event); | 545 void CompleteEvent(TimelineEvent* event); |
| 457 }; | 546 }; |
| 458 | 547 |
| 459 | 548 |
| 460 // A recorder that stores events in chains of blocks of events. | 549 // A recorder that stores events in chains of blocks of events. |
| 461 // NOTE: This recorder will continue to allocate blocks until it exhausts | 550 // NOTE: This recorder will continue to allocate blocks until it exhausts |
| 462 // memory. | 551 // memory. |
| 463 class TimelineEventEndlessRecorder : public TimelineEventRecorder { | 552 class TimelineEventEndlessRecorder : public TimelineEventRecorder { |
| 464 public: | 553 public: |
| 465 TimelineEventEndlessRecorder(); | 554 TimelineEventEndlessRecorder(); |
| 466 | 555 |
| 467 // Acquire a new block of events. | |
| 468 // Takes a lock. | |
| 469 // Recorder owns the block and it should be filled by only one thread. | |
| 470 TimelineEventBlock* GetNewBlock(); | |
| 471 | |
| 472 TimelineEventBlock* GetHeadBlock(); | |
| 473 | |
| 474 // It is expected that this function is only called when an isolate is | |
| 475 // shutting itself down. | |
| 476 // NOTE: Calling this while threads are filling in their blocks is not safe | 556 // NOTE: Calling this while threads are filling in their blocks is not safe |
| 477 // and there are no checks in place to ensure that doesn't happen. | 557 // and there are no checks in place to ensure that doesn't happen. |
| 478 // TODO(koda): Add isolate count to |ThreadRegistry| and verify that it is 1. | 558 // TODO(koda): Add isolate count to |ThreadRegistry| and verify that it is 1. |
| 479 void PrintJSON(JSONStream* js); | 559 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); |
| 480 | 560 |
| 481 protected: | 561 protected: |
| 482 TimelineEvent* StartEvent(); | 562 TimelineEvent* StartEvent(); |
| 483 void CompleteEvent(TimelineEvent* event); | 563 void CompleteEvent(TimelineEvent* event); |
| 564 TimelineEventBlock* GetNewBlockLocked(Isolate* isolate); |
| 565 TimelineEventBlock* GetHeadBlockLocked(); |
| 484 | 566 |
| 485 TimelineEventBlock* GetNewBlockLocked(); | 567 void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter) const; |
| 486 void PrintJSONEvents(JSONArray* array) const; | |
| 487 | 568 |
| 488 // Useful only for testing. Only works for one thread. | 569 // Useful only for testing. Only works for one thread. |
| 489 void Clear(); | 570 void Clear(); |
| 490 | 571 |
| 491 TimelineEventBlock* head_; | 572 TimelineEventBlock* head_; |
| 492 intptr_t block_index_; | 573 intptr_t block_index_; |
| 493 | 574 |
| 494 friend class TimelineTestHelper; | 575 friend class TimelineTestHelper; |
| 495 }; | 576 }; |
| 496 | 577 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 510 TimelineEventBlock* Next(); | 591 TimelineEventBlock* Next(); |
| 511 | 592 |
| 512 private: | 593 private: |
| 513 TimelineEventBlock* current_; | 594 TimelineEventBlock* current_; |
| 514 TimelineEventRecorder* recorder_; | 595 TimelineEventRecorder* recorder_; |
| 515 }; | 596 }; |
| 516 | 597 |
| 517 } // namespace dart | 598 } // namespace dart |
| 518 | 599 |
| 519 #endif // VM_TIMELINE_H_ | 600 #endif // VM_TIMELINE_H_ |
| OLD | NEW |