Chromium Code Reviews| 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 #include "platform/globals.h" | |
| 5 #ifndef PRODUCT | 6 #ifndef PRODUCT |
| 6 | 7 |
| 7 #include <errno.h> | 8 #include <errno.h> |
| 8 #include <fcntl.h> | 9 #include <fcntl.h> |
| 9 #include <cstdlib> | 10 #include <cstdlib> |
| 10 | 11 |
| 12 #if defined(HOST_OS_FUCHSIA) | |
| 13 #include "apps/tracing/lib/trace/event.h" | |
| 14 #endif | |
| 15 | |
| 11 #include "vm/atomic.h" | 16 #include "vm/atomic.h" |
| 12 #include "vm/isolate.h" | 17 #include "vm/isolate.h" |
| 13 #include "vm/json_stream.h" | 18 #include "vm/json_stream.h" |
| 14 #include "vm/lockers.h" | 19 #include "vm/lockers.h" |
| 15 #include "vm/log.h" | 20 #include "vm/log.h" |
| 16 #include "vm/object.h" | 21 #include "vm/object.h" |
| 17 #include "vm/service_event.h" | 22 #include "vm/service_event.h" |
| 18 #include "vm/thread.h" | 23 #include "vm/thread.h" |
| 19 #include "vm/timeline.h" | 24 #include "vm/timeline.h" |
| 20 | 25 |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 Init(kInstant, label); | 412 Init(kInstant, label); |
| 408 set_timestamp0(micros); | 413 set_timestamp0(micros); |
| 409 } | 414 } |
| 410 | 415 |
| 411 | 416 |
| 412 void TimelineEvent::Duration(const char* label, | 417 void TimelineEvent::Duration(const char* label, |
| 413 int64_t start_micros, | 418 int64_t start_micros, |
| 414 int64_t end_micros, | 419 int64_t end_micros, |
| 415 int64_t thread_start_micros, | 420 int64_t thread_start_micros, |
| 416 int64_t thread_end_micros) { | 421 int64_t thread_end_micros) { |
| 417 Init(kDuration, label); | 422 Init(kDuration, label); |
|
rmacnak
2017/07/10 23:39:01
Maybe emit a Fuchsia tracing duration start here i
zra
2017/07/11 17:38:04
event->Duration() and event->Complete() are both c
| |
| 418 set_timestamp0(start_micros); | 423 set_timestamp0(start_micros); |
| 419 set_timestamp1(end_micros); | 424 set_timestamp1(end_micros); |
| 420 set_thread_timestamp0(thread_start_micros); | 425 set_thread_timestamp0(thread_start_micros); |
| 421 set_thread_timestamp1(thread_end_micros); | 426 set_thread_timestamp1(thread_end_micros); |
| 422 } | 427 } |
| 423 | 428 |
| 424 | 429 |
| 425 void TimelineEvent::Begin(const char* label, | 430 void TimelineEvent::Begin(const char* label, |
| 426 int64_t micros, | 431 int64_t micros, |
| 427 int64_t thread_micros) { | 432 int64_t thread_micros) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 509 } | 514 } |
| 510 | 515 |
| 511 | 516 |
| 512 void TimelineEvent::StealArguments(intptr_t arguments_length, | 517 void TimelineEvent::StealArguments(intptr_t arguments_length, |
| 513 TimelineEventArgument* arguments) { | 518 TimelineEventArgument* arguments) { |
| 514 arguments_length_ = arguments_length; | 519 arguments_length_ = arguments_length; |
| 515 arguments_ = arguments; | 520 arguments_ = arguments; |
| 516 } | 521 } |
| 517 | 522 |
| 518 | 523 |
| 524 #if defined(HOST_OS_FUCHSIA) | |
| 525 | |
| 526 // TODO(zra): The functions below emit Dart's timeline events all as category | |
| 527 // "dart". Instead, we could have finer-grained categories that make use of | |
| 528 // the name of the timeline stream, e.g. "VM", "GC", etc. | |
| 529 | |
| 530 #define FUCHSIA_EVENT_ARGS_LIST(V) \ | |
| 531 V(Begin, TRACE_DURATION_BEGIN) \ | |
| 532 V(End, TRACE_DURATION_END) | |
| 533 | |
| 534 #define EMIT_FUCHSIA_EVENT(__name, __macro) \ | |
| 535 static void EmitFuchsia##__name##Event(const char* label, \ | |
| 536 TimelineEventArgument* arguments, \ | |
| 537 intptr_t arguments_length) { \ | |
| 538 if (arguments_length == 0) { \ | |
| 539 __macro("dart", label); \ | |
| 540 } else if (arguments_length == 1) { \ | |
| 541 __macro("dart", label, arguments[0].name, \ | |
| 542 const_cast<const char*>(arguments[0].value)); \ | |
| 543 } else { \ | |
| 544 __macro("dart", label, arguments[0].name, \ | |
| 545 const_cast<const char*>(arguments[0].value), \ | |
| 546 arguments[1].name, \ | |
| 547 const_cast<const char*>(arguments[1].value)); \ | |
| 548 } \ | |
| 549 } | |
| 550 | |
| 551 FUCHSIA_EVENT_ARGS_LIST(EMIT_FUCHSIA_EVENT) | |
| 552 #undef EMIT_FUCHSIA_EVENT | |
| 553 | |
| 554 #define FUCHSIA_EVENT_ID_ARGS_LIST(V) \ | |
| 555 V(Instant, TRACE_INSTANT, ::tracing::EventScope) \ | |
| 556 V(AsyncBegin, TRACE_ASYNC_BEGIN, int64_t) \ | |
| 557 V(AsyncEnd, TRACE_ASYNC_END, int64_t) \ | |
| 558 V(AsyncInstant, TRACE_ASYNC_INSTANT, int64_t) | |
| 559 | |
| 560 #define EMIT_FUCHSIA_EVENT(__name, __macro, __id_typ) \ | |
| 561 static void EmitFuchsia##__name##Event(const char* label, \ | |
| 562 __id_typ id, \ | |
| 563 TimelineEventArgument* arguments, \ | |
| 564 intptr_t arguments_length) { \ | |
| 565 if (arguments_length == 0) { \ | |
| 566 __macro("dart", label, id); \ | |
| 567 } else if (arguments_length == 1) { \ | |
| 568 __macro("dart", label, id, arguments[0].name, \ | |
| 569 const_cast<const char*>(arguments[0].value)); \ | |
| 570 } else { \ | |
| 571 __macro("dart", label, id, arguments[0].name, \ | |
| 572 const_cast<const char*>(arguments[0].value), \ | |
| 573 arguments[1].name, \ | |
| 574 const_cast<const char*>(arguments[1].value)); \ | |
| 575 } \ | |
| 576 } | |
| 577 | |
| 578 FUCHSIA_EVENT_ID_ARGS_LIST(EMIT_FUCHSIA_EVENT) | |
| 579 #undef EMIT_FUCHSIA_EVENT | |
| 580 | |
| 581 | |
| 582 void TimelineEvent::EmitFuchsiaEvent() { | |
| 583 switch (event_type()) { | |
| 584 case kBegin: | |
| 585 EmitFuchsiaBeginEvent(label_, arguments_, arguments_length_); | |
| 586 break; | |
| 587 case kEnd: | |
| 588 EmitFuchsiaEndEvent(label_, arguments_, arguments_length_); | |
| 589 break; | |
| 590 case kInstant: | |
| 591 EmitFuchsiaInstantEvent( | |
| 592 label_, TRACE_SCOPE_THREAD, arguments_, arguments_length_); | |
| 593 break; | |
| 594 case kAsyncBegin: | |
| 595 EmitFuchsiaAsyncBeginEvent( | |
| 596 label_, AsyncId(), arguments_, arguments_length_); | |
| 597 break; | |
| 598 case kAsyncEnd: | |
| 599 EmitFuchsiaAsyncEndEvent( | |
| 600 label_, AsyncId(), arguments_, arguments_length_); | |
| 601 break; | |
| 602 case kAsyncInstant: | |
| 603 EmitFuchsiaAsyncInstantEvent( | |
| 604 label_, AsyncId(), arguments_, arguments_length_); | |
| 605 break; | |
| 606 default: | |
| 607 // TODO(zra): Figure out what to do with kDuration, kCounter, and | |
|
rmacnak
2017/07/10 23:39:02
Duration is the most common event type.
zra
2017/07/11 17:38:04
Except when coming through Dart_TimelineEvent(), k
| |
| 608 // kMetadata. | |
| 609 break; | |
| 610 } | |
| 611 } | |
| 612 #endif | |
| 613 | |
| 614 | |
| 519 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { | 615 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { |
| 520 ASSERT(buffer != NULL); | 616 ASSERT(buffer != NULL); |
| 521 ASSERT(buffer_size > 0); | 617 ASSERT(buffer_size > 0); |
| 522 buffer[0] = '\0'; | 618 buffer[0] = '\0'; |
| 523 intptr_t length = 0; | 619 intptr_t length = 0; |
| 524 int64_t pid = OS::ProcessId(); | 620 int64_t pid = OS::ProcessId(); |
| 525 switch (event_type()) { | 621 switch (event_type()) { |
| 526 case kBegin: { | 622 case kBegin: { |
| 527 length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, label()); | 623 length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, label()); |
| 528 } break; | 624 } break; |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 906 arguments_ = NULL; | 1002 arguments_ = NULL; |
| 907 } | 1003 } |
| 908 | 1004 |
| 909 | 1005 |
| 910 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, | 1006 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, |
| 911 const char* label) | 1007 const char* label) |
| 912 : TimelineEventScope(stream, label) { | 1008 : TimelineEventScope(stream, label) { |
| 913 if (!FLAG_support_timeline || !enabled()) { | 1009 if (!FLAG_support_timeline || !enabled()) { |
| 914 return; | 1010 return; |
| 915 } | 1011 } |
| 1012 #if defined(HOST_OS_FUCHSIA) | |
| 1013 TRACE_DURATION_BEGIN("dart", label); | |
| 1014 #else | |
| 916 timestamp_ = OS::GetCurrentMonotonicMicros(); | 1015 timestamp_ = OS::GetCurrentMonotonicMicros(); |
| 917 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); | 1016 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
| 1017 #endif | |
| 918 } | 1018 } |
| 919 | 1019 |
| 920 | 1020 |
| 921 TimelineDurationScope::TimelineDurationScope(Thread* thread, | 1021 TimelineDurationScope::TimelineDurationScope(Thread* thread, |
| 922 TimelineStream* stream, | 1022 TimelineStream* stream, |
| 923 const char* label) | 1023 const char* label) |
| 924 : TimelineEventScope(thread, stream, label) { | 1024 : TimelineEventScope(thread, stream, label) { |
| 925 if (!FLAG_support_timeline || !enabled()) { | 1025 if (!FLAG_support_timeline || !enabled()) { |
| 926 return; | 1026 return; |
| 927 } | 1027 } |
| 1028 #if defined(HOST_OS_FUCHSIA) | |
| 1029 TRACE_DURATION_BEGIN("dart", label); | |
| 1030 #else | |
| 928 timestamp_ = OS::GetCurrentMonotonicMicros(); | 1031 timestamp_ = OS::GetCurrentMonotonicMicros(); |
| 929 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); | 1032 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
| 1033 #endif | |
| 930 } | 1034 } |
| 931 | 1035 |
| 932 | 1036 |
| 933 TimelineDurationScope::~TimelineDurationScope() { | 1037 TimelineDurationScope::~TimelineDurationScope() { |
| 934 if (!FLAG_support_timeline) { | 1038 if (!FLAG_support_timeline) { |
| 935 return; | 1039 return; |
| 936 } | 1040 } |
| 937 if (!ShouldEmitEvent()) { | 1041 if (!ShouldEmitEvent()) { |
| 938 return; | 1042 return; |
| 939 } | 1043 } |
| 1044 #if defined(HOST_OS_FUCHSIA) | |
| 1045 EmitFuchsiaEndEvent(label(), arguments(), arguments_length()); | |
| 1046 #else | |
| 940 TimelineEvent* event = stream()->StartEvent(); | 1047 TimelineEvent* event = stream()->StartEvent(); |
| 941 if (event == NULL) { | 1048 if (event == NULL) { |
| 942 // Stream is now disabled. | 1049 // Stream is now disabled. |
| 943 return; | 1050 return; |
| 944 } | 1051 } |
| 945 ASSERT(event != NULL); | 1052 ASSERT(event != NULL); |
| 946 // Emit a duration event. | 1053 // Emit a duration event. |
| 947 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), | 1054 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), |
| 948 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); | 1055 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); |
| 949 StealArguments(event); | 1056 StealArguments(event); |
| 950 event->Complete(); | 1057 event->Complete(); |
| 1058 #endif | |
| 951 } | 1059 } |
| 952 | 1060 |
| 953 | 1061 |
| 954 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, | 1062 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, |
| 955 const char* label) | 1063 const char* label) |
| 956 : TimelineEventScope(stream, label) { | 1064 : TimelineEventScope(stream, label) { |
| 957 if (!FLAG_support_timeline) { | 1065 if (!FLAG_support_timeline) { |
| 958 return; | 1066 return; |
| 959 } | 1067 } |
| 960 EmitBegin(); | 1068 EmitBegin(); |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1375 | 1483 |
| 1376 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) | 1484 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) |
| 1377 : TimelineEventFixedBufferRecorder(capacity), systrace_fd_(-1) { | 1485 : TimelineEventFixedBufferRecorder(capacity), systrace_fd_(-1) { |
| 1378 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) | 1486 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) |
| 1379 const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; | 1487 const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; |
| 1380 systrace_fd_ = open(kSystracePath, O_WRONLY); | 1488 systrace_fd_ = open(kSystracePath, O_WRONLY); |
| 1381 if ((systrace_fd_ < 0) && FLAG_trace_timeline) { | 1489 if ((systrace_fd_ < 0) && FLAG_trace_timeline) { |
| 1382 OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", | 1490 OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", |
| 1383 kSystracePath); | 1491 kSystracePath); |
| 1384 } | 1492 } |
| 1493 #elif defined(HOST_OS_FUCHSIA) | |
| 1494 // Nothing to do. | |
| 1385 #else | 1495 #else |
| 1386 OS::PrintErr( | 1496 OS::PrintErr( |
| 1387 "Warning: The systrace timeline recorder is equivalent to the" | 1497 "Warning: The systrace timeline recorder is equivalent to the" |
| 1388 "ring recorder on this platform."); | 1498 "ring recorder on this platform."); |
| 1389 #endif | 1499 #endif |
| 1390 } | 1500 } |
| 1391 | 1501 |
| 1392 | 1502 |
| 1393 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { | 1503 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { |
| 1394 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) | 1504 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1424 const intptr_t event_length = | 1534 const intptr_t event_length = |
| 1425 event->PrintSystrace(&buffer[0], kBufferLength); | 1535 event->PrintSystrace(&buffer[0], kBufferLength); |
| 1426 if (event_length > 0) { | 1536 if (event_length > 0) { |
| 1427 ssize_t __result; | 1537 ssize_t __result; |
| 1428 // Repeatedly attempt the write while we are being interrupted. | 1538 // Repeatedly attempt the write while we are being interrupted. |
| 1429 do { | 1539 do { |
| 1430 __result = write(systrace_fd_, buffer, event_length); | 1540 __result = write(systrace_fd_, buffer, event_length); |
| 1431 } while ((__result == -1L) && (errno == EINTR)); | 1541 } while ((__result == -1L) && (errno == EINTR)); |
| 1432 } | 1542 } |
| 1433 } | 1543 } |
| 1544 #elif defined(HOST_OS_FUCHSIA) | |
| 1545 event->EmitFuchsiaEvent(); | |
| 1434 #endif | 1546 #endif |
| 1435 ThreadBlockCompleteEvent(event); | 1547 ThreadBlockCompleteEvent(event); |
| 1436 } | 1548 } |
| 1437 | 1549 |
| 1438 | 1550 |
| 1439 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() { | 1551 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() { |
| 1440 // TODO(johnmccutchan): This function should only hand out blocks | 1552 // TODO(johnmccutchan): This function should only hand out blocks |
| 1441 // which have been marked as finished. | 1553 // which have been marked as finished. |
| 1442 if (block_cursor_ == num_blocks_) { | 1554 if (block_cursor_ == num_blocks_) { |
| 1443 block_cursor_ = 0; | 1555 block_cursor_ = 0; |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1774 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 1886 TimelineEventBlock* TimelineEventBlockIterator::Next() { |
| 1775 ASSERT(current_ != NULL); | 1887 ASSERT(current_ != NULL); |
| 1776 TimelineEventBlock* r = current_; | 1888 TimelineEventBlock* r = current_; |
| 1777 current_ = current_->next(); | 1889 current_ = current_->next(); |
| 1778 return r; | 1890 return r; |
| 1779 } | 1891 } |
| 1780 | 1892 |
| 1781 } // namespace dart | 1893 } // namespace dart |
| 1782 | 1894 |
| 1783 #endif // !PRODUCT | 1895 #endif // !PRODUCT |
| OLD | NEW |