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 RUNTIME_VM_TIMELINE_H_ | 5 #ifndef RUNTIME_VM_TIMELINE_H_ |
6 #define RUNTIME_VM_TIMELINE_H_ | 6 #define RUNTIME_VM_TIMELINE_H_ |
7 | 7 |
8 #include "include/dart_tools_api.h" | 8 #include "include/dart_tools_api.h" |
9 | 9 |
10 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 V(GC, false) \ | 37 V(GC, false) \ |
38 V(Isolate, false) \ | 38 V(Isolate, false) \ |
39 V(VM, false) | 39 V(VM, false) |
40 | 40 |
41 // A stream of timeline events. A stream has a name and can be enabled or | 41 // A stream of timeline events. A stream has a name and can be enabled or |
42 // disabled (globally and per isolate). | 42 // disabled (globally and per isolate). |
43 class TimelineStream { | 43 class TimelineStream { |
44 public: | 44 public: |
45 TimelineStream(); | 45 TimelineStream(); |
46 | 46 |
47 void Init(const char* name, | 47 void Init(const char* name, bool enabled); |
48 bool enabled); | |
49 | 48 |
50 const char* name() const { | 49 const char* name() const { return name_; } |
51 return name_; | |
52 } | |
53 | 50 |
54 bool enabled() const { | 51 bool enabled() const { return enabled_ != 0; } |
55 return enabled_ != 0; | |
56 } | |
57 | 52 |
58 void set_enabled(bool enabled) { | 53 void set_enabled(bool enabled) { enabled_ = enabled ? 1 : 0; } |
59 enabled_ = enabled ? 1 : 0; | |
60 } | |
61 | 54 |
62 // Records an event. Will return |NULL| if not enabled. The returned | 55 // Records an event. Will return |NULL| if not enabled. The returned |
63 // |TimelineEvent| is in an undefined state and must be initialized. | 56 // |TimelineEvent| is in an undefined state and must be initialized. |
64 // NOTE: It is not allowed to call StartEvent again without completing | 57 // NOTE: It is not allowed to call StartEvent again without completing |
65 // the first event. | 58 // the first event. |
66 TimelineEvent* StartEvent(); | 59 TimelineEvent* StartEvent(); |
67 | 60 |
68 static intptr_t enabled_offset() { | 61 static intptr_t enabled_offset() { |
69 return OFFSET_OF(TimelineStream, enabled_); | 62 return OFFSET_OF(TimelineStream, enabled_); |
70 } | 63 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 // Completes this event with pre-serialized JSON. Copies |json|. | 216 // Completes this event with pre-serialized JSON. Copies |json|. |
224 void CompleteWithPreSerializedJSON(const char* json); | 217 void CompleteWithPreSerializedJSON(const char* json); |
225 | 218 |
226 // Set the number of arguments in the event. | 219 // Set the number of arguments in the event. |
227 void SetNumArguments(intptr_t length); | 220 void SetNumArguments(intptr_t length); |
228 // |name| must be a compile time constant. Takes ownership of |argument|. | 221 // |name| must be a compile time constant. Takes ownership of |argument|. |
229 void SetArgument(intptr_t i, const char* name, char* argument); | 222 void SetArgument(intptr_t i, const char* name, char* argument); |
230 // |name| must be a compile time constant. Copies |argument|. | 223 // |name| must be a compile time constant. Copies |argument|. |
231 void CopyArgument(intptr_t i, const char* name, const char* argument); | 224 void CopyArgument(intptr_t i, const char* name, const char* argument); |
232 // |name| must be a compile time constant. | 225 // |name| must be a compile time constant. |
233 void FormatArgument(intptr_t i, | 226 void FormatArgument(intptr_t i, const char* name, const char* fmt, ...) |
234 const char* name, | 227 PRINTF_ATTRIBUTE(4, 5); |
235 const char* fmt, ...) PRINTF_ATTRIBUTE(4, 5); | |
236 | 228 |
237 void StealArguments(intptr_t arguments_length, | 229 void StealArguments(intptr_t arguments_length, |
238 TimelineEventArgument* arguments); | 230 TimelineEventArgument* arguments); |
239 // Mandatory to call when this event is completely filled out. | 231 // Mandatory to call when this event is completely filled out. |
240 void Complete(); | 232 void Complete(); |
241 | 233 |
242 EventType event_type() const { | 234 EventType event_type() const { return EventTypeField::decode(state_); } |
243 return EventTypeField::decode(state_); | |
244 } | |
245 | 235 |
246 bool IsFinishedDuration() const { | 236 bool IsFinishedDuration() const { |
247 return (event_type() == kDuration) && (timestamp1_ > timestamp0_); | 237 return (event_type() == kDuration) && (timestamp1_ > timestamp0_); |
248 } | 238 } |
249 | 239 |
250 bool HasThreadCPUTime() const; | 240 bool HasThreadCPUTime() const; |
251 int64_t ThreadCPUTimeDuration() const; | 241 int64_t ThreadCPUTimeDuration() const; |
252 int64_t ThreadCPUTimeOrigin() const; | 242 int64_t ThreadCPUTimeOrigin() const; |
253 | 243 |
254 int64_t TimeOrigin() const; | 244 int64_t TimeOrigin() const; |
255 int64_t AsyncId() const; | 245 int64_t AsyncId() const; |
256 int64_t TimeDuration() const; | 246 int64_t TimeDuration() const; |
257 int64_t TimeEnd() const { | 247 int64_t TimeEnd() const { |
258 ASSERT(IsFinishedDuration()); | 248 ASSERT(IsFinishedDuration()); |
259 return timestamp1_; | 249 return timestamp1_; |
260 } | 250 } |
261 | 251 |
262 // The lowest time value stored in this event. | 252 // The lowest time value stored in this event. |
263 int64_t LowTime() const; | 253 int64_t LowTime() const; |
264 // The highest time value stored in this event. | 254 // The highest time value stored in this event. |
265 int64_t HighTime() const; | 255 int64_t HighTime() const; |
266 | 256 |
267 void PrintJSON(JSONStream* stream) const; | 257 void PrintJSON(JSONStream* stream) const; |
268 | 258 |
269 ThreadId thread() const { | 259 ThreadId thread() const { return thread_; } |
270 return thread_; | |
271 } | |
272 | 260 |
273 void set_thread(ThreadId tid) { | 261 void set_thread(ThreadId tid) { thread_ = tid; } |
274 thread_ = tid; | |
275 } | |
276 | 262 |
277 Dart_Port isolate_id() const { | 263 Dart_Port isolate_id() const { return isolate_id_; } |
278 return isolate_id_; | |
279 } | |
280 | 264 |
281 const char* label() const { | 265 const char* label() const { return label_; } |
282 return label_; | |
283 } | |
284 | 266 |
285 // Does this duration end before |micros| ? | 267 // Does this duration end before |micros| ? |
286 bool DurationFinishedBefore(int64_t micros) const { | 268 bool DurationFinishedBefore(int64_t micros) const { |
287 return TimeEnd() <= micros; | 269 return TimeEnd() <= micros; |
288 } | 270 } |
289 | 271 |
290 bool IsDuration() const { | 272 bool IsDuration() const { return (event_type() == kDuration); } |
291 return (event_type() == kDuration); | |
292 } | |
293 | 273 |
294 bool IsBegin() const { | 274 bool IsBegin() const { return (event_type() == kBegin); } |
295 return (event_type() == kBegin); | |
296 } | |
297 | 275 |
298 bool IsEnd() const { | 276 bool IsEnd() const { return (event_type() == kEnd); } |
299 return (event_type() == kEnd); | |
300 } | |
301 | 277 |
302 // Is this event a synchronous begin or end event? | 278 // Is this event a synchronous begin or end event? |
303 bool IsBeginOrEnd() const { | 279 bool IsBeginOrEnd() const { return IsBegin() || IsEnd(); } |
304 return IsBegin() || IsEnd(); | |
305 } | |
306 | 280 |
307 // Does this duration fully contain |other| ? | 281 // Does this duration fully contain |other| ? |
308 bool DurationContains(TimelineEvent* other) const { | 282 bool DurationContains(TimelineEvent* other) const { |
309 ASSERT(IsFinishedDuration()); | 283 ASSERT(IsFinishedDuration()); |
310 if (other->IsBegin()) { | 284 if (other->IsBegin()) { |
311 if (other->TimeOrigin() < TimeOrigin()) { | 285 if (other->TimeOrigin() < TimeOrigin()) { |
312 return false; | 286 return false; |
313 } | 287 } |
314 if (other->TimeOrigin() > TimeEnd()) { | 288 if (other->TimeOrigin() > TimeEnd()) { |
315 return false; | 289 return false; |
(...skipping 10 matching lines...) Expand all Loading... |
326 if (other->TimeOrigin() > TimeEnd()) { | 300 if (other->TimeOrigin() > TimeEnd()) { |
327 return false; | 301 return false; |
328 } | 302 } |
329 if (other->TimeEnd() > TimeEnd()) { | 303 if (other->TimeEnd() > TimeEnd()) { |
330 return false; | 304 return false; |
331 } | 305 } |
332 return true; | 306 return true; |
333 } | 307 } |
334 } | 308 } |
335 | 309 |
336 bool Within(int64_t time_origin_micros, | 310 bool Within(int64_t time_origin_micros, int64_t time_extent_micros); |
337 int64_t time_extent_micros); | |
338 | 311 |
339 const char* GetSerializedJSON() const; | 312 const char* GetSerializedJSON() const; |
340 | 313 |
341 void set_owns_label(bool owns_label) { | 314 void set_owns_label(bool owns_label) { |
342 state_ = OwnsLabelBit::update(owns_label, state_); | 315 state_ = OwnsLabelBit::update(owns_label, state_); |
343 } | 316 } |
344 | 317 |
345 // Returns the number of bytes written into |buffer|. | 318 // Returns the number of bytes written into |buffer|. |
346 intptr_t PrintSystrace(char* buffer, intptr_t buffer_size); | 319 intptr_t PrintSystrace(char* buffer, intptr_t buffer_size); |
347 | 320 |
(...skipping 21 matching lines...) Expand all Loading... |
369 void set_thread_timestamp0(int64_t value) { | 342 void set_thread_timestamp0(int64_t value) { |
370 ASSERT(thread_timestamp0_ == -1); | 343 ASSERT(thread_timestamp0_ == -1); |
371 thread_timestamp0_ = value; | 344 thread_timestamp0_ = value; |
372 } | 345 } |
373 | 346 |
374 void set_thread_timestamp1(int64_t value) { | 347 void set_thread_timestamp1(int64_t value) { |
375 ASSERT(thread_timestamp1_ == -1); | 348 ASSERT(thread_timestamp1_ == -1); |
376 thread_timestamp1_ = value; | 349 thread_timestamp1_ = value; |
377 } | 350 } |
378 | 351 |
379 bool pre_serialized_json() const { | 352 bool pre_serialized_json() const { return PreSerializedJSON::decode(state_); } |
380 return PreSerializedJSON::decode(state_); | |
381 } | |
382 | 353 |
383 void set_pre_serialized_json(bool pre_serialized_json) { | 354 void set_pre_serialized_json(bool pre_serialized_json) { |
384 state_ = PreSerializedJSON::update(pre_serialized_json, state_); | 355 state_ = PreSerializedJSON::update(pre_serialized_json, state_); |
385 } | 356 } |
386 | 357 |
387 bool owns_label() const { | 358 bool owns_label() const { return OwnsLabelBit::decode(state_); } |
388 return OwnsLabelBit::decode(state_); | |
389 } | |
390 | 359 |
391 enum StateBits { | 360 enum StateBits { |
392 kEventTypeBit = 0, // reserve 4 bits for type. | 361 kEventTypeBit = 0, // reserve 4 bits for type. |
393 kPreSerializedJSON = 4, | 362 kPreSerializedJSON = 4, |
394 kOwnsLabelBit = 5, | 363 kOwnsLabelBit = 5, |
395 kNextBit = 6, | 364 kNextBit = 6, |
396 }; | 365 }; |
397 | 366 |
398 class EventTypeField : public BitField<uword, EventType, kEventTypeBit, 4> {}; | 367 class EventTypeField : public BitField<uword, EventType, kEventTypeBit, 4> {}; |
399 class PreSerializedJSON : | 368 class PreSerializedJSON |
400 public BitField<uword, bool, kPreSerializedJSON, 1> {}; | 369 : public BitField<uword, bool, kPreSerializedJSON, 1> {}; |
401 class OwnsLabelBit : public BitField<uword, bool, kOwnsLabelBit, 1> {}; | 370 class OwnsLabelBit : public BitField<uword, bool, kOwnsLabelBit, 1> {}; |
402 | 371 |
403 int64_t timestamp0_; | 372 int64_t timestamp0_; |
404 int64_t timestamp1_; | 373 int64_t timestamp1_; |
405 int64_t thread_timestamp0_; | 374 int64_t thread_timestamp0_; |
406 int64_t thread_timestamp1_; | 375 int64_t thread_timestamp1_; |
407 TimelineEventArgument* arguments_; | 376 TimelineEventArgument* arguments_; |
408 intptr_t arguments_length_; | 377 intptr_t arguments_length_; |
409 uword state_; | 378 uword state_; |
410 const char* label_; | 379 const char* label_; |
411 const char* category_; | 380 const char* category_; |
412 ThreadId thread_; | 381 ThreadId thread_; |
413 Dart_Port isolate_id_; | 382 Dart_Port isolate_id_; |
414 | 383 |
415 friend class TimelineEventRecorder; | 384 friend class TimelineEventRecorder; |
416 friend class TimelineEventEndlessRecorder; | 385 friend class TimelineEventEndlessRecorder; |
417 friend class TimelineEventRingRecorder; | 386 friend class TimelineEventRingRecorder; |
418 friend class TimelineEventStartupRecorder; | 387 friend class TimelineEventStartupRecorder; |
419 friend class TimelineEventSystraceRecorder; | 388 friend class TimelineEventSystraceRecorder; |
420 friend class TimelineStream; | 389 friend class TimelineStream; |
421 friend class TimelineTestHelper; | 390 friend class TimelineTestHelper; |
422 DISALLOW_COPY_AND_ASSIGN(TimelineEvent); | 391 DISALLOW_COPY_AND_ASSIGN(TimelineEvent); |
423 }; | 392 }; |
424 | 393 |
425 | 394 |
426 #ifndef PRODUCT | 395 #ifndef PRODUCT |
427 #define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, name, function) \ | 396 #define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, name, function) \ |
428 TimelineDurationScope tds(thread, \ | 397 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), name); \ |
429 Timeline::GetCompilerStream(), \ | |
430 name); \ | |
431 if (tds.enabled()) { \ | 398 if (tds.enabled()) { \ |
432 tds.SetNumArguments(1); \ | 399 tds.SetNumArguments(1); \ |
433 tds.CopyArgument( \ | 400 tds.CopyArgument(0, "function", \ |
434 0, \ | 401 function.ToLibNamePrefixedQualifiedCString()); \ |
435 "function", \ | |
436 function.ToLibNamePrefixedQualifiedCString()); \ | |
437 } | 402 } |
438 | 403 |
439 #define TIMELINE_FUNCTION_GC_DURATION(thread, name) \ | 404 #define TIMELINE_FUNCTION_GC_DURATION(thread, name) \ |
440 TimelineDurationScope tds(thread, Timeline::GetGCStream(), name); | 405 TimelineDurationScope tds(thread, Timeline::GetGCStream(), name); |
441 #else | 406 #else |
442 #define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, name, function) | 407 #define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, name, function) |
443 #define TIMELINE_FUNCTION_GC_DURATION(thread, name) | 408 #define TIMELINE_FUNCTION_GC_DURATION(thread, name) |
444 #endif // !PRODUCT | 409 #endif // !PRODUCT |
445 | 410 |
446 // See |TimelineDurationScope| and |TimelineBeginEndScope|. | 411 // See |TimelineDurationScope| and |TimelineBeginEndScope|. |
447 class TimelineEventScope : public StackResource { | 412 class TimelineEventScope : public StackResource { |
448 public: | 413 public: |
449 bool enabled() const { | 414 bool enabled() const { return enabled_; } |
450 return enabled_; | |
451 } | |
452 | 415 |
453 void SetNumArguments(intptr_t length); | 416 void SetNumArguments(intptr_t length); |
454 | 417 |
455 void SetArgument(intptr_t i, const char* name, char* argument); | 418 void SetArgument(intptr_t i, const char* name, char* argument); |
456 | 419 |
457 void CopyArgument(intptr_t i, const char* name, const char* argument); | 420 void CopyArgument(intptr_t i, const char* name, const char* argument); |
458 | 421 |
459 void FormatArgument(intptr_t i, | 422 void FormatArgument(intptr_t i, const char* name, const char* fmt, ...) |
460 const char* name, | 423 PRINTF_ATTRIBUTE(4, 5); |
461 const char* fmt, ...) PRINTF_ATTRIBUTE(4, 5); | |
462 | 424 |
463 protected: | 425 protected: |
464 TimelineEventScope(TimelineStream* stream, | 426 TimelineEventScope(TimelineStream* stream, const char* label); |
465 const char* label); | |
466 | 427 |
467 TimelineEventScope(Thread* thread, | 428 TimelineEventScope(Thread* thread, TimelineStream* stream, const char* label); |
468 TimelineStream* stream, | |
469 const char* label); | |
470 | 429 |
471 bool ShouldEmitEvent() const { | 430 bool ShouldEmitEvent() const { return enabled_; } |
472 return enabled_; | |
473 } | |
474 | 431 |
475 void set_enabled(bool enabled) { | 432 void set_enabled(bool enabled) { enabled_ = enabled; } |
476 enabled_ = enabled; | |
477 } | |
478 | 433 |
479 const char* label() const { | 434 const char* label() const { return label_; } |
480 return label_; | |
481 } | |
482 | 435 |
483 TimelineStream* stream() const { | 436 TimelineStream* stream() const { return stream_; } |
484 return stream_; | |
485 } | |
486 | 437 |
487 virtual ~TimelineEventScope(); | 438 virtual ~TimelineEventScope(); |
488 | 439 |
489 void StealArguments(TimelineEvent* event); | 440 void StealArguments(TimelineEvent* event); |
490 | 441 |
491 private: | 442 private: |
492 void Init(); | 443 void Init(); |
493 void FreeArguments(); | 444 void FreeArguments(); |
494 | 445 |
495 TimelineStream* stream_; | 446 TimelineStream* stream_; |
496 const char* label_; | 447 const char* label_; |
497 TimelineEventArgument* arguments_; | 448 TimelineEventArgument* arguments_; |
498 intptr_t arguments_length_; | 449 intptr_t arguments_length_; |
499 bool enabled_; | 450 bool enabled_; |
500 | 451 |
501 DISALLOW_COPY_AND_ASSIGN(TimelineEventScope); | 452 DISALLOW_COPY_AND_ASSIGN(TimelineEventScope); |
502 }; | 453 }; |
503 | 454 |
504 | 455 |
505 class TimelineDurationScope : public TimelineEventScope { | 456 class TimelineDurationScope : public TimelineEventScope { |
506 public: | 457 public: |
507 TimelineDurationScope(TimelineStream* stream, | 458 TimelineDurationScope(TimelineStream* stream, const char* label); |
508 const char* label); | |
509 | 459 |
510 TimelineDurationScope(Thread* thread, | 460 TimelineDurationScope(Thread* thread, |
511 TimelineStream* stream, | 461 TimelineStream* stream, |
512 const char* label); | 462 const char* label); |
513 | 463 |
514 ~TimelineDurationScope(); | 464 ~TimelineDurationScope(); |
515 | 465 |
516 private: | 466 private: |
517 int64_t timestamp_; | 467 int64_t timestamp_; |
518 int64_t thread_timestamp_; | 468 int64_t thread_timestamp_; |
519 | 469 |
520 DISALLOW_COPY_AND_ASSIGN(TimelineDurationScope); | 470 DISALLOW_COPY_AND_ASSIGN(TimelineDurationScope); |
521 }; | 471 }; |
522 | 472 |
523 | 473 |
524 class TimelineBeginEndScope : public TimelineEventScope { | 474 class TimelineBeginEndScope : public TimelineEventScope { |
525 public: | 475 public: |
526 TimelineBeginEndScope(TimelineStream* stream, | 476 TimelineBeginEndScope(TimelineStream* stream, const char* label); |
527 const char* label); | |
528 | 477 |
529 TimelineBeginEndScope(Thread* thread, | 478 TimelineBeginEndScope(Thread* thread, |
530 TimelineStream* stream, | 479 TimelineStream* stream, |
531 const char* label); | 480 const char* label); |
532 | 481 |
533 ~TimelineBeginEndScope(); | 482 ~TimelineBeginEndScope(); |
534 | 483 |
535 private: | 484 private: |
536 void EmitBegin(); | 485 void EmitBegin(); |
537 void EmitEnd(); | 486 void EmitEnd(); |
538 | 487 |
539 DISALLOW_COPY_AND_ASSIGN(TimelineBeginEndScope); | 488 DISALLOW_COPY_AND_ASSIGN(TimelineBeginEndScope); |
540 }; | 489 }; |
541 | 490 |
542 | 491 |
543 // A block of |TimelineEvent|s. Not thread safe. | 492 // A block of |TimelineEvent|s. Not thread safe. |
544 class TimelineEventBlock { | 493 class TimelineEventBlock { |
545 public: | 494 public: |
546 static const intptr_t kBlockSize = 64; | 495 static const intptr_t kBlockSize = 64; |
547 | 496 |
548 explicit TimelineEventBlock(intptr_t index); | 497 explicit TimelineEventBlock(intptr_t index); |
549 ~TimelineEventBlock(); | 498 ~TimelineEventBlock(); |
550 | 499 |
551 TimelineEventBlock* next() const { | 500 TimelineEventBlock* next() const { return next_; } |
552 return next_; | 501 void set_next(TimelineEventBlock* next) { next_ = next; } |
553 } | |
554 void set_next(TimelineEventBlock* next) { | |
555 next_ = next; | |
556 } | |
557 | 502 |
558 intptr_t length() const { | 503 intptr_t length() const { return length_; } |
559 return length_; | |
560 } | |
561 | 504 |
562 intptr_t block_index() const { | 505 intptr_t block_index() const { return block_index_; } |
563 return block_index_; | |
564 } | |
565 | 506 |
566 bool IsEmpty() const { | 507 bool IsEmpty() const { return length_ == 0; } |
567 return length_ == 0; | |
568 } | |
569 | 508 |
570 bool IsFull() const { | 509 bool IsFull() const { return length_ == kBlockSize; } |
571 return length_ == kBlockSize; | |
572 } | |
573 | 510 |
574 TimelineEvent* At(intptr_t index) { | 511 TimelineEvent* At(intptr_t index) { |
575 ASSERT(index >= 0); | 512 ASSERT(index >= 0); |
576 ASSERT(index < kBlockSize); | 513 ASSERT(index < kBlockSize); |
577 return &events_[index]; | 514 return &events_[index]; |
578 } | 515 } |
579 | 516 |
580 const TimelineEvent* At(intptr_t index) const { | 517 const TimelineEvent* At(intptr_t index) const { |
581 ASSERT(index >= 0); | 518 ASSERT(index >= 0); |
582 ASSERT(index < kBlockSize); | 519 ASSERT(index < kBlockSize); |
583 return &events_[index]; | 520 return &events_[index]; |
584 } | 521 } |
585 | 522 |
586 // Attempt to sniff the timestamp from the first event. | 523 // Attempt to sniff the timestamp from the first event. |
587 int64_t LowerTimeBound() const; | 524 int64_t LowerTimeBound() const; |
588 | 525 |
589 // Returns false if |this| violates any of the following invariants: | 526 // Returns false if |this| violates any of the following invariants: |
590 // - events in the block come from one thread. | 527 // - events in the block come from one thread. |
591 // - events have monotonically increasing timestamps. | 528 // - events have monotonically increasing timestamps. |
592 bool CheckBlock(); | 529 bool CheckBlock(); |
593 | 530 |
594 // Call Reset on all events and set length to 0. | 531 // Call Reset on all events and set length to 0. |
595 void Reset(); | 532 void Reset(); |
596 | 533 |
597 // Only safe to access under the recorder's lock. | 534 // Only safe to access under the recorder's lock. |
598 bool in_use() const { | 535 bool in_use() const { return in_use_; } |
599 return in_use_; | |
600 } | |
601 | 536 |
602 // Only safe to access under the recorder's lock. | 537 // Only safe to access under the recorder's lock. |
603 ThreadId thread_id() const { | 538 ThreadId thread_id() const { return thread_id_; } |
604 return thread_id_; | |
605 } | |
606 | 539 |
607 protected: | 540 protected: |
608 void PrintJSON(JSONStream* stream) const; | 541 void PrintJSON(JSONStream* stream) const; |
609 | 542 |
610 TimelineEvent* StartEvent(); | 543 TimelineEvent* StartEvent(); |
611 | 544 |
612 TimelineEvent events_[kBlockSize]; | 545 TimelineEvent events_[kBlockSize]; |
613 TimelineEventBlock* next_; | 546 TimelineEventBlock* next_; |
614 intptr_t length_; | 547 intptr_t length_; |
615 intptr_t block_index_; | 548 intptr_t block_index_; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 return !block->IsEmpty() && !block->in_use(); | 583 return !block->IsEmpty() && !block->in_use(); |
651 } | 584 } |
652 | 585 |
653 virtual bool IncludeEvent(TimelineEvent* event) { | 586 virtual bool IncludeEvent(TimelineEvent* event) { |
654 if (event == NULL) { | 587 if (event == NULL) { |
655 return false; | 588 return false; |
656 } | 589 } |
657 return event->IsValid(); | 590 return event->IsValid(); |
658 } | 591 } |
659 | 592 |
660 int64_t time_origin_micros() const { | 593 int64_t time_origin_micros() const { return time_origin_micros_; } |
661 return time_origin_micros_; | |
662 } | |
663 | 594 |
664 int64_t time_extent_micros() const { | 595 int64_t time_extent_micros() const { return time_extent_micros_; } |
665 return time_extent_micros_; | |
666 } | |
667 | 596 |
668 private: | 597 private: |
669 int64_t time_origin_micros_; | 598 int64_t time_origin_micros_; |
670 int64_t time_extent_micros_; | 599 int64_t time_extent_micros_; |
671 }; | 600 }; |
672 | 601 |
673 | 602 |
674 class IsolateTimelineEventFilter : public TimelineEventFilter { | 603 class IsolateTimelineEventFilter : public TimelineEventFilter { |
675 public: | 604 public: |
676 explicit IsolateTimelineEventFilter(Dart_Port isolate_id, | 605 explicit IsolateTimelineEventFilter(Dart_Port isolate_id, |
677 int64_t time_origin_micros = -1, | 606 int64_t time_origin_micros = -1, |
678 int64_t time_extent_micros = -1); | 607 int64_t time_extent_micros = -1); |
679 | 608 |
680 bool IncludeBlock(TimelineEventBlock* block) { | 609 bool IncludeBlock(TimelineEventBlock* block) { |
681 if (block == NULL) { | 610 if (block == NULL) { |
682 return false; | 611 return false; |
683 } | 612 } |
684 // Not empty, not in use, and isolate match. | 613 // Not empty, not in use, and isolate match. |
685 return !block->IsEmpty() && !block->in_use(); | 614 return !block->IsEmpty() && !block->in_use(); |
686 } | 615 } |
687 | 616 |
688 bool IncludeEvent(TimelineEvent* event) { | 617 bool IncludeEvent(TimelineEvent* event) { |
689 return event->IsValid() && | 618 return event->IsValid() && (event->isolate_id() == isolate_id_); |
690 (event->isolate_id() == isolate_id_); | |
691 } | 619 } |
692 | 620 |
693 private: | 621 private: |
694 Dart_Port isolate_id_; | 622 Dart_Port isolate_id_; |
695 }; | 623 }; |
696 | 624 |
697 | 625 |
698 // Recorder of |TimelineEvent|s. | 626 // Recorder of |TimelineEvent|s. |
699 class TimelineEventRecorder { | 627 class TimelineEventRecorder { |
700 public: | 628 public: |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 | 703 |
776 | 704 |
777 // A recorder that stores events in a buffer of fixed capacity. When the buffer | 705 // A recorder that stores events in a buffer of fixed capacity. When the buffer |
778 // is full, new events overwrite old events. | 706 // is full, new events overwrite old events. |
779 class TimelineEventRingRecorder : public TimelineEventFixedBufferRecorder { | 707 class TimelineEventRingRecorder : public TimelineEventFixedBufferRecorder { |
780 public: | 708 public: |
781 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity) | 709 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity) |
782 : TimelineEventFixedBufferRecorder(capacity) {} | 710 : TimelineEventFixedBufferRecorder(capacity) {} |
783 ~TimelineEventRingRecorder() {} | 711 ~TimelineEventRingRecorder() {} |
784 | 712 |
785 const char* name() const { | 713 const char* name() const { return "Ring"; } |
786 return "Ring"; | |
787 } | |
788 | 714 |
789 protected: | 715 protected: |
790 TimelineEventBlock* GetNewBlockLocked(); | 716 TimelineEventBlock* GetNewBlockLocked(); |
791 }; | 717 }; |
792 | 718 |
793 | 719 |
794 // A recorder that writes events to Android Systrace. Events are also stored in | 720 // A recorder that writes events to Android Systrace. Events are also stored in |
795 // a buffer of fixed capacity. When the buffer is full, new events overwrite | 721 // a buffer of fixed capacity. When the buffer is full, new events overwrite |
796 // old events. | 722 // old events. |
797 class TimelineEventSystraceRecorder | 723 class TimelineEventSystraceRecorder : public TimelineEventFixedBufferRecorder { |
798 : public TimelineEventFixedBufferRecorder { | |
799 public: | 724 public: |
800 explicit TimelineEventSystraceRecorder(intptr_t capacity = kDefaultCapacity); | 725 explicit TimelineEventSystraceRecorder(intptr_t capacity = kDefaultCapacity); |
801 | 726 |
802 ~TimelineEventSystraceRecorder(); | 727 ~TimelineEventSystraceRecorder(); |
803 | 728 |
804 const char* name() const { | 729 const char* name() const { return "Systrace"; } |
805 return "Systrace"; | |
806 } | |
807 | 730 |
808 protected: | 731 protected: |
809 TimelineEventBlock* GetNewBlockLocked(); | 732 TimelineEventBlock* GetNewBlockLocked(); |
810 void CompleteEvent(TimelineEvent* event); | 733 void CompleteEvent(TimelineEvent* event); |
811 | 734 |
812 int systrace_fd_; | 735 int systrace_fd_; |
813 }; | 736 }; |
814 | 737 |
815 | 738 |
816 // A recorder that stores events in a buffer of fixed capacity. When the buffer | 739 // A recorder that stores events in a buffer of fixed capacity. When the buffer |
817 // is full, new events are dropped. | 740 // is full, new events are dropped. |
818 class TimelineEventStartupRecorder : public TimelineEventFixedBufferRecorder { | 741 class TimelineEventStartupRecorder : public TimelineEventFixedBufferRecorder { |
819 public: | 742 public: |
820 explicit TimelineEventStartupRecorder(intptr_t capacity = kDefaultCapacity) | 743 explicit TimelineEventStartupRecorder(intptr_t capacity = kDefaultCapacity) |
821 : TimelineEventFixedBufferRecorder(capacity) {} | 744 : TimelineEventFixedBufferRecorder(capacity) {} |
822 ~TimelineEventStartupRecorder() {} | 745 ~TimelineEventStartupRecorder() {} |
823 | 746 |
824 const char* name() const { | 747 const char* name() const { return "Startup"; } |
825 return "Startup"; | |
826 } | |
827 | 748 |
828 protected: | 749 protected: |
829 TimelineEventBlock* GetNewBlockLocked(); | 750 TimelineEventBlock* GetNewBlockLocked(); |
830 }; | 751 }; |
831 | 752 |
832 | 753 |
833 // An abstract recorder that calls |OnEvent| whenever an event is complete. | 754 // An abstract recorder that calls |OnEvent| whenever an event is complete. |
834 // This should only be used for testing. | 755 // This should only be used for testing. |
835 class TimelineEventCallbackRecorder : public TimelineEventRecorder { | 756 class TimelineEventCallbackRecorder : public TimelineEventRecorder { |
836 public: | 757 public: |
837 TimelineEventCallbackRecorder(); | 758 TimelineEventCallbackRecorder(); |
838 ~TimelineEventCallbackRecorder(); | 759 ~TimelineEventCallbackRecorder(); |
839 | 760 |
840 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); | 761 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); |
841 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter); | 762 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter); |
842 | 763 |
843 // Called when |event| is completed. It is unsafe to keep a reference to | 764 // Called when |event| is completed. It is unsafe to keep a reference to |
844 // |event| as it may be freed as soon as this function returns. | 765 // |event| as it may be freed as soon as this function returns. |
845 virtual void OnEvent(TimelineEvent* event) = 0; | 766 virtual void OnEvent(TimelineEvent* event) = 0; |
846 | 767 |
847 const char* name() const { | 768 const char* name() const { return "Callback"; } |
848 return "Callback"; | |
849 } | |
850 | 769 |
851 protected: | 770 protected: |
852 TimelineEventBlock* GetNewBlockLocked() { | 771 TimelineEventBlock* GetNewBlockLocked() { return NULL; } |
853 return NULL; | 772 TimelineEventBlock* GetHeadBlockLocked() { return NULL; } |
854 } | 773 void Clear() {} |
855 TimelineEventBlock* GetHeadBlockLocked() { | |
856 return NULL; | |
857 } | |
858 void Clear() { | |
859 } | |
860 TimelineEvent* StartEvent(); | 774 TimelineEvent* StartEvent(); |
861 void CompleteEvent(TimelineEvent* event); | 775 void CompleteEvent(TimelineEvent* event); |
862 }; | 776 }; |
863 | 777 |
864 | 778 |
865 // A recorder that stores events in chains of blocks of events. | 779 // A recorder that stores events in chains of blocks of events. |
866 // NOTE: This recorder will continue to allocate blocks until it exhausts | 780 // NOTE: This recorder will continue to allocate blocks until it exhausts |
867 // memory. | 781 // memory. |
868 class TimelineEventEndlessRecorder : public TimelineEventRecorder { | 782 class TimelineEventEndlessRecorder : public TimelineEventRecorder { |
869 public: | 783 public: |
870 TimelineEventEndlessRecorder(); | 784 TimelineEventEndlessRecorder(); |
871 | 785 |
872 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); | 786 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); |
873 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter); | 787 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter); |
874 | 788 |
875 const char* name() const { | 789 const char* name() const { return "Endless"; } |
876 return "Endless"; | |
877 } | |
878 | 790 |
879 protected: | 791 protected: |
880 TimelineEvent* StartEvent(); | 792 TimelineEvent* StartEvent(); |
881 void CompleteEvent(TimelineEvent* event); | 793 void CompleteEvent(TimelineEvent* event); |
882 TimelineEventBlock* GetNewBlockLocked(); | 794 TimelineEventBlock* GetNewBlockLocked(); |
883 TimelineEventBlock* GetHeadBlockLocked(); | 795 TimelineEventBlock* GetHeadBlockLocked(); |
884 void Clear(); | 796 void Clear(); |
885 | 797 |
886 void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter); | 798 void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter); |
887 | 799 |
(...skipping 20 matching lines...) Expand all Loading... |
908 | 820 |
909 private: | 821 private: |
910 TimelineEventBlock* current_; | 822 TimelineEventBlock* current_; |
911 TimelineEventRecorder* recorder_; | 823 TimelineEventRecorder* recorder_; |
912 }; | 824 }; |
913 | 825 |
914 | 826 |
915 } // namespace dart | 827 } // namespace dart |
916 | 828 |
917 #endif // RUNTIME_VM_TIMELINE_H_ | 829 #endif // RUNTIME_VM_TIMELINE_H_ |
OLD | NEW |