| 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 PRODUCT |     5 #ifndef PRODUCT | 
|     6  |     6  | 
|     7 #include <errno.h> |     7 #include <errno.h> | 
|     8 #include <fcntl.h> |     8 #include <fcntl.h> | 
|     9 #include <cstdlib> |     9 #include <cstdlib> | 
|    10  |    10  | 
|    11 #include "vm/atomic.h" |    11 #include "vm/atomic.h" | 
|    12 #include "vm/isolate.h" |    12 #include "vm/isolate.h" | 
|    13 #include "vm/json_stream.h" |    13 #include "vm/json_stream.h" | 
|    14 #include "vm/lockers.h" |    14 #include "vm/lockers.h" | 
|    15 #include "vm/log.h" |    15 #include "vm/log.h" | 
|    16 #include "vm/object.h" |    16 #include "vm/object.h" | 
|    17 #include "vm/service_event.h" |    17 #include "vm/service_event.h" | 
|    18 #include "vm/thread.h" |    18 #include "vm/thread.h" | 
|    19 #include "vm/timeline.h" |    19 #include "vm/timeline.h" | 
|    20  |    20  | 
|    21 namespace dart { |    21 namespace dart { | 
|    22  |    22  | 
|    23 DEFINE_FLAG(bool, complete_timeline, false, "Record the complete timeline"); |    23 DEFINE_FLAG(bool, complete_timeline, false, "Record the complete timeline"); | 
|    24 DEFINE_FLAG(bool, startup_timeline, false, "Record the startup timeline"); |    24 DEFINE_FLAG(bool, startup_timeline, false, "Record the startup timeline"); | 
|    25 DEFINE_FLAG(bool, systrace_timeline, false, "Record the timeline to systrace"); |    25 DEFINE_FLAG(bool, systrace_timeline, false, "Record the timeline to systrace"); | 
|    26 DEFINE_FLAG(bool, trace_timeline, false, |    26 DEFINE_FLAG(bool, trace_timeline, false, "Trace timeline backend"); | 
|    27             "Trace timeline backend"); |    27 DEFINE_FLAG(bool, | 
|    28 DEFINE_FLAG(bool, trace_timeline_analysis, false, |    28             trace_timeline_analysis, | 
 |    29             false, | 
|    29             "Trace timeline analysis backend"); |    30             "Trace timeline analysis backend"); | 
|    30 DEFINE_FLAG(bool, timing, false, |    31 DEFINE_FLAG(bool, | 
 |    32             timing, | 
 |    33             false, | 
|    31             "Dump isolate timing information from timeline."); |    34             "Dump isolate timing information from timeline."); | 
|    32 DEFINE_FLAG(charp, timeline_dir, NULL, |    35 DEFINE_FLAG(charp, | 
 |    36             timeline_dir, | 
 |    37             NULL, | 
|    33             "Enable all timeline trace streams and output VM global trace " |    38             "Enable all timeline trace streams and output VM global trace " | 
|    34             "into specified directory."); |    39             "into specified directory."); | 
|    35 DEFINE_FLAG(charp, timeline_streams, NULL, |    40 DEFINE_FLAG(charp, | 
 |    41             timeline_streams, | 
 |    42             NULL, | 
|    36             "Comma separated list of timeline streams to record. " |    43             "Comma separated list of timeline streams to record. " | 
|    37             "Valid values: all, API, Compiler, Dart, Debugger, Embedder, " |    44             "Valid values: all, API, Compiler, Dart, Debugger, Embedder, " | 
|    38             "GC, Isolate, and VM."); |    45             "GC, Isolate, and VM."); | 
|    39 DEFINE_FLAG(charp, timeline_recorder, "ring", |    46 DEFINE_FLAG(charp, | 
 |    47             timeline_recorder, | 
 |    48             "ring", | 
|    40             "Select the timeline recorder used. " |    49             "Select the timeline recorder used. " | 
|    41             "Valid values: ring, endless, startup, and systrace.") |    50             "Valid values: ring, endless, startup, and systrace.") | 
|    42  |    51  | 
|    43 // Implementation notes: |    52 // Implementation notes: | 
|    44 // |    53 // | 
|    45 // Writing events: |    54 // Writing events: | 
|    46 // |TimelineEvent|s are written into |TimelineEventBlock|s. Each |Thread| caches |    55 // |TimelineEvent|s are written into |TimelineEventBlock|s. Each |Thread| caches | 
|    47 // a |TimelineEventBlock| object so that it can write events without |    56 // a |TimelineEventBlock| object so that it can write events without | 
|    48 // synchronizing with other threads in the system. Even though the |Thread| owns |    57 // synchronizing with other threads in the system. Even though the |Thread| owns | 
|    49 // the |TimelineEventBlock| the block may need to be reclaimed by the reporting |    58 // the |TimelineEventBlock| the block may need to be reclaimed by the reporting | 
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   157   } |   166   } | 
|   158   for (intptr_t i = 0; i < streams->length(); i++) { |   167   for (intptr_t i = 0; i < streams->length(); i++) { | 
|   159     free((*streams)[i]); |   168     free((*streams)[i]); | 
|   160   } |   169   } | 
|   161   delete streams; |   170   delete streams; | 
|   162 } |   171 } | 
|   163  |   172  | 
|   164  |   173  | 
|   165 // Returns true if |streams| contains |stream| or "all". Not case sensitive. |   174 // Returns true if |streams| contains |stream| or "all". Not case sensitive. | 
|   166 static bool HasStream(MallocGrowableArray<char*>* streams, const char* stream) { |   175 static bool HasStream(MallocGrowableArray<char*>* streams, const char* stream) { | 
|   167   if ((FLAG_timeline_dir != NULL) || |   176   if ((FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline || | 
|   168       FLAG_timing || FLAG_complete_timeline || FLAG_startup_timeline) { |   177       FLAG_startup_timeline) { | 
|   169     return true; |   178     return true; | 
|   170   } |   179   } | 
|   171   for (intptr_t i = 0; i < streams->length(); i++) { |   180   for (intptr_t i = 0; i < streams->length(); i++) { | 
|   172     const char* checked_stream = (*streams)[i]; |   181     const char* checked_stream = (*streams)[i]; | 
|   173     if ((strstr(checked_stream, "all") != NULL) || |   182     if ((strstr(checked_stream, "all") != NULL) || | 
|   174         (strstr(checked_stream, stream) != NULL)) { |   183         (strstr(checked_stream, stream) != NULL)) { | 
|   175       return true; |   184       return true; | 
|   176     } |   185     } | 
|   177   } |   186   } | 
|   178   return false; |   187   return false; | 
|   179 } |   188 } | 
|   180  |   189  | 
|   181  |   190  | 
|   182 void Timeline::InitOnce() { |   191 void Timeline::InitOnce() { | 
|   183   ASSERT(recorder_ == NULL); |   192   ASSERT(recorder_ == NULL); | 
|   184   recorder_ = CreateTimelineRecorder(); |   193   recorder_ = CreateTimelineRecorder(); | 
|   185   ASSERT(recorder_ != NULL); |   194   ASSERT(recorder_ != NULL); | 
|   186   enabled_streams_ = GetEnabledByDefaultTimelineStreams(); |   195   enabled_streams_ = GetEnabledByDefaultTimelineStreams(); | 
|   187   // Global overrides. |   196 // Global overrides. | 
|   188 #define TIMELINE_STREAM_FLAG_DEFAULT(name, not_used)                           \ |   197 #define TIMELINE_STREAM_FLAG_DEFAULT(name, not_used)                           \ | 
|   189   stream_##name##_.Init(#name,                                                 \ |   198   stream_##name##_.Init(#name, HasStream(enabled_streams_, #name)); | 
|   190                         HasStream(enabled_streams_, #name)); |  | 
|   191   TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT) |   199   TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT) | 
|   192 #undef TIMELINE_STREAM_FLAG_DEFAULT |   200 #undef TIMELINE_STREAM_FLAG_DEFAULT | 
|   193  |   201  | 
|   194   if (Timeline::stream_Embedder_.enabled() && |   202   if (Timeline::stream_Embedder_.enabled() && | 
|   195       (Timeline::get_start_recording_cb() != NULL)) { |   203       (Timeline::get_start_recording_cb() != NULL)) { | 
|   196     Timeline::get_start_recording_cb()(); |   204     Timeline::get_start_recording_cb()(); | 
|   197   } |   205   } | 
|   198 } |   206 } | 
|   199  |   207  | 
|   200  |   208  | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|   219  |   227  | 
|   220   if (Timeline::stream_Embedder_.enabled() && |   228   if (Timeline::stream_Embedder_.enabled() && | 
|   221       (Timeline::get_stop_recording_cb() != NULL)) { |   229       (Timeline::get_stop_recording_cb() != NULL)) { | 
|   222     Timeline::get_stop_recording_cb()(); |   230     Timeline::get_stop_recording_cb()(); | 
|   223   } |   231   } | 
|   224  |   232  | 
|   225   if (FLAG_timeline_dir != NULL) { |   233   if (FLAG_timeline_dir != NULL) { | 
|   226     recorder_->WriteTo(FLAG_timeline_dir); |   234     recorder_->WriteTo(FLAG_timeline_dir); | 
|   227   } |   235   } | 
|   228  |   236  | 
|   229   // Disable global streams. |   237 // Disable global streams. | 
|   230 #define TIMELINE_STREAM_DISABLE(name, not_used)                                \ |   238 #define TIMELINE_STREAM_DISABLE(name, not_used)                                \ | 
|   231   Timeline::stream_##name##_.set_enabled(false); |   239   Timeline::stream_##name##_.set_enabled(false); | 
|   232   TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE) |   240   TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE) | 
|   233 #undef TIMELINE_STREAM_DISABLE |   241 #undef TIMELINE_STREAM_DISABLE | 
|   234   delete recorder_; |   242   delete recorder_; | 
|   235   recorder_ = NULL; |   243   recorder_ = NULL; | 
|   236   if (enabled_streams_ != NULL) { |   244   if (enabled_streams_ != NULL) { | 
|   237     FreeEnabledByDefaultTimelineStreams(enabled_streams_); |   245     FreeEnabledByDefaultTimelineStreams(enabled_streams_); | 
|   238     enabled_streams_ = NULL; |   246     enabled_streams_ = NULL; | 
|   239   } |   247   } | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   271   JSONObject obj(js); |   279   JSONObject obj(js); | 
|   272   obj.AddProperty("type", "TimelineFlags"); |   280   obj.AddProperty("type", "TimelineFlags"); | 
|   273   TimelineEventRecorder* recorder = Timeline::recorder(); |   281   TimelineEventRecorder* recorder = Timeline::recorder(); | 
|   274   if (recorder == NULL) { |   282   if (recorder == NULL) { | 
|   275     obj.AddProperty("recorderName", "null"); |   283     obj.AddProperty("recorderName", "null"); | 
|   276   } else { |   284   } else { | 
|   277     obj.AddProperty("recorderName", recorder->name()); |   285     obj.AddProperty("recorderName", recorder->name()); | 
|   278   } |   286   } | 
|   279   { |   287   { | 
|   280     JSONArray availableStreams(&obj, "availableStreams"); |   288     JSONArray availableStreams(&obj, "availableStreams"); | 
|   281 #define ADD_STREAM_NAME(name, not_used)                                        \ |   289 #define ADD_STREAM_NAME(name, not_used) availableStreams.AddValue(#name); | 
|   282     availableStreams.AddValue(#name); |   290     TIMELINE_STREAM_LIST(ADD_STREAM_NAME); | 
|   283 TIMELINE_STREAM_LIST(ADD_STREAM_NAME); |  | 
|   284 #undef ADD_STREAM_NAME |   291 #undef ADD_STREAM_NAME | 
|   285   } |   292   } | 
|   286   { |   293   { | 
|   287     JSONArray recordedStreams(&obj, "recordedStreams"); |   294     JSONArray recordedStreams(&obj, "recordedStreams"); | 
|   288 #define ADD_RECORDED_STREAM_NAME(name, not_used)                               \ |   295 #define ADD_RECORDED_STREAM_NAME(name, not_used)                               \ | 
|   289     if (stream_##name##_.enabled()) {                                          \ |   296   if (stream_##name##_.enabled()) {                                            \ | 
|   290       recordedStreams.AddValue(#name);                                         \ |   297     recordedStreams.AddValue(#name);                                           \ | 
|   291     } |   298   } | 
|   292 TIMELINE_STREAM_LIST(ADD_RECORDED_STREAM_NAME); |   299     TIMELINE_STREAM_LIST(ADD_RECORDED_STREAM_NAME); | 
|   293 #undef ADD_RECORDED_STREAM_NAME |   300 #undef ADD_RECORDED_STREAM_NAME | 
|   294   } |   301   } | 
|   295 } |   302 } | 
|   296  |   303  | 
|   297  |   304  | 
|   298 void Timeline::Clear() { |   305 void Timeline::Clear() { | 
|   299   TimelineEventRecorder* recorder = Timeline::recorder(); |   306   TimelineEventRecorder* recorder = Timeline::recorder(); | 
|   300   if (recorder == NULL) { |   307   if (recorder == NULL) { | 
|   301     return; |   308     return; | 
|   302   } |   309   } | 
|   303   ReclaimCachedBlocksFromThreads(); |   310   ReclaimCachedBlocksFromThreads(); | 
|   304   recorder->Clear(); |   311   recorder->Clear(); | 
|   305 } |   312 } | 
|   306  |   313  | 
|   307  |   314  | 
|   308 TimelineEventRecorder* Timeline::recorder_ = NULL; |   315 TimelineEventRecorder* Timeline::recorder_ = NULL; | 
|   309 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL; |   316 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL; | 
|   310 Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL; |   317 Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL; | 
|   311 Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL; |   318 Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL; | 
|   312  |   319  | 
|   313 #define TIMELINE_STREAM_DEFINE(name, enabled_by_default)                       \ |   320 #define TIMELINE_STREAM_DEFINE(name, enabled_by_default)                       \ | 
|   314   TimelineStream Timeline::stream_##name##_; |   321   TimelineStream Timeline::stream_##name##_; | 
|   315   TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE) |   322 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE) | 
|   316 #undef TIMELINE_STREAM_DEFINE |   323 #undef TIMELINE_STREAM_DEFINE | 
|   317  |   324  | 
|   318 TimelineEvent::TimelineEvent() |   325 TimelineEvent::TimelineEvent() | 
|   319     : timestamp0_(0), |   326     : timestamp0_(0), | 
|   320       timestamp1_(0), |   327       timestamp1_(0), | 
|   321       thread_timestamp0_(-1), |   328       thread_timestamp0_(-1), | 
|   322       thread_timestamp1_(-1), |   329       thread_timestamp1_(-1), | 
|   323       arguments_(NULL), |   330       arguments_(NULL), | 
|   324       arguments_length_(0), |   331       arguments_length_(0), | 
|   325       state_(0), |   332       state_(0), | 
|   326       label_(NULL), |   333       label_(NULL), | 
|   327       category_(""), |   334       category_(""), | 
|   328       thread_(OSThread::kInvalidThreadId), |   335       thread_(OSThread::kInvalidThreadId), | 
|   329       isolate_id_(ILLEGAL_PORT) { |   336       isolate_id_(ILLEGAL_PORT) {} | 
|   330 } |  | 
|   331  |   337  | 
|   332  |   338  | 
|   333 TimelineEvent::~TimelineEvent() { |   339 TimelineEvent::~TimelineEvent() { | 
|   334   Reset(); |   340   Reset(); | 
|   335 } |   341 } | 
|   336  |   342  | 
|   337  |   343  | 
|   338 void TimelineEvent::Reset() { |   344 void TimelineEvent::Reset() { | 
|   339   if (owns_label() && label_ != NULL) { |   345   if (owns_label() && label_ != NULL) { | 
|   340     free(const_cast<char*>(label_)); |   346     free(const_cast<char*>(label_)); | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   383  |   389  | 
|   384 void TimelineEvent::DurationBegin(const char* label, |   390 void TimelineEvent::DurationBegin(const char* label, | 
|   385                                   int64_t micros, |   391                                   int64_t micros, | 
|   386                                   int64_t thread_micros) { |   392                                   int64_t thread_micros) { | 
|   387   Init(kDuration, label); |   393   Init(kDuration, label); | 
|   388   set_timestamp0(micros); |   394   set_timestamp0(micros); | 
|   389   set_thread_timestamp0(thread_micros); |   395   set_thread_timestamp0(thread_micros); | 
|   390 } |   396 } | 
|   391  |   397  | 
|   392  |   398  | 
|   393 void TimelineEvent::DurationEnd(int64_t micros, |   399 void TimelineEvent::DurationEnd(int64_t micros, int64_t thread_micros) { | 
|   394                                 int64_t thread_micros) { |  | 
|   395   ASSERT(timestamp1_ == 0); |   400   ASSERT(timestamp1_ == 0); | 
|   396   set_timestamp1(micros); |   401   set_timestamp1(micros); | 
|   397   set_thread_timestamp1(thread_micros); |   402   set_thread_timestamp1(thread_micros); | 
|   398 } |   403 } | 
|   399  |   404  | 
|   400  |   405  | 
|   401 void TimelineEvent::Instant(const char* label, |   406 void TimelineEvent::Instant(const char* label, int64_t micros) { | 
|   402                             int64_t micros) { |  | 
|   403   Init(kInstant, label); |   407   Init(kInstant, label); | 
|   404   set_timestamp0(micros); |   408   set_timestamp0(micros); | 
|   405 } |   409 } | 
|   406  |   410  | 
|   407  |   411  | 
|   408 void TimelineEvent::Duration(const char* label, |   412 void TimelineEvent::Duration(const char* label, | 
|   409                              int64_t start_micros, |   413                              int64_t start_micros, | 
|   410                              int64_t end_micros, |   414                              int64_t end_micros, | 
|   411                              int64_t thread_start_micros, |   415                              int64_t thread_start_micros, | 
|   412                              int64_t thread_end_micros) { |   416                              int64_t thread_end_micros) { | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   470  |   474  | 
|   471  |   475  | 
|   472 void TimelineEvent::SetArgument(intptr_t i, const char* name, char* argument) { |   476 void TimelineEvent::SetArgument(intptr_t i, const char* name, char* argument) { | 
|   473   ASSERT(i >= 0); |   477   ASSERT(i >= 0); | 
|   474   ASSERT(i < arguments_length_); |   478   ASSERT(i < arguments_length_); | 
|   475   arguments_[i].name = name; |   479   arguments_[i].name = name; | 
|   476   arguments_[i].value = argument; |   480   arguments_[i].value = argument; | 
|   477 } |   481 } | 
|   478  |   482  | 
|   479  |   483  | 
|   480 void TimelineEvent::FormatArgument(intptr_t i, const char* name, |   484 void TimelineEvent::FormatArgument(intptr_t i, | 
|   481                                    const char* fmt, ...) { |   485                                    const char* name, | 
 |   486                                    const char* fmt, | 
 |   487                                    ...) { | 
|   482   ASSERT(i >= 0); |   488   ASSERT(i >= 0); | 
|   483   ASSERT(i < arguments_length_); |   489   ASSERT(i < arguments_length_); | 
|   484   va_list args; |   490   va_list args; | 
|   485   va_start(args, fmt); |   491   va_start(args, fmt); | 
|   486   intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |   492   intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); | 
|   487   va_end(args); |   493   va_end(args); | 
|   488  |   494  | 
|   489   char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |   495   char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 
|   490   va_list args2; |   496   va_list args2; | 
|   491   va_start(args2, fmt); |   497   va_start(args2, fmt); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|   512  |   518  | 
|   513 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { |   519 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { | 
|   514   ASSERT(buffer != NULL); |   520   ASSERT(buffer != NULL); | 
|   515   ASSERT(buffer_size > 0); |   521   ASSERT(buffer_size > 0); | 
|   516   buffer[0] = '\0'; |   522   buffer[0] = '\0'; | 
|   517   intptr_t length = 0; |   523   intptr_t length = 0; | 
|   518   int64_t pid = OS::ProcessId(); |   524   int64_t pid = OS::ProcessId(); | 
|   519   switch (event_type()) { |   525   switch (event_type()) { | 
|   520     case kBegin: { |   526     case kBegin: { | 
|   521       length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, label()); |   527       length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, label()); | 
|   522     } |   528     } break; | 
|   523     break; |  | 
|   524     case kEnd: { |   529     case kEnd: { | 
|   525       length = OS::SNPrint(buffer, buffer_size, "E"); |   530       length = OS::SNPrint(buffer, buffer_size, "E"); | 
|   526     } |   531     } break; | 
|   527     break; |  | 
|   528     case kCounter: { |   532     case kCounter: { | 
|   529       if (arguments_length_ > 0) { |   533       if (arguments_length_ > 0) { | 
|   530         // We only report the first counter value. |   534         // We only report the first counter value. | 
|   531         length = OS::SNPrint(buffer, buffer_size, |   535         length = OS::SNPrint(buffer, buffer_size, "C|%" Pd64 "|%s|%s", pid, | 
|   532                              "C|%" Pd64 "|%s|%s", |   536                              label(), arguments_[0].value); | 
|   533                              pid, |  | 
|   534                              label(), |  | 
|   535                              arguments_[0].value); |  | 
|   536       } |   537       } | 
|   537     } |   538     } | 
|   538     default: |   539     default: | 
|   539       // Ignore event types that we cannot serialize to the Systrace format. |   540       // Ignore event types that we cannot serialize to the Systrace format. | 
|   540     break; |   541       break; | 
|   541   } |   542   } | 
|   542   return length; |   543   return length; | 
|   543 } |   544 } | 
|   544  |   545  | 
|   545  |   546  | 
|   546 void TimelineEvent::Complete() { |   547 void TimelineEvent::Complete() { | 
|   547   TimelineEventRecorder* recorder = Timeline::recorder(); |   548   TimelineEventRecorder* recorder = Timeline::recorder(); | 
|   548   if (recorder != NULL) { |   549   if (recorder != NULL) { | 
|   549     recorder->CompleteEvent(this); |   550     recorder->CompleteEvent(this); | 
|   550   } |   551   } | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|   566  |   567  | 
|   567 void TimelineEvent::StreamInit(TimelineStream* stream) { |   568 void TimelineEvent::StreamInit(TimelineStream* stream) { | 
|   568   if (stream != NULL) { |   569   if (stream != NULL) { | 
|   569     category_ = stream->name(); |   570     category_ = stream->name(); | 
|   570   } else { |   571   } else { | 
|   571     category_ = ""; |   572     category_ = ""; | 
|   572   } |   573   } | 
|   573 } |   574 } | 
|   574  |   575  | 
|   575  |   576  | 
|   576 void TimelineEvent::Init(EventType event_type, |   577 void TimelineEvent::Init(EventType event_type, const char* label) { | 
|   577                          const char* label) { |  | 
|   578   ASSERT(label != NULL); |   578   ASSERT(label != NULL); | 
|   579   state_ = 0; |   579   state_ = 0; | 
|   580   timestamp0_ = 0; |   580   timestamp0_ = 0; | 
|   581   timestamp1_ = 0; |   581   timestamp1_ = 0; | 
|   582   thread_timestamp0_ = -1; |   582   thread_timestamp0_ = -1; | 
|   583   thread_timestamp1_ = -1; |   583   thread_timestamp1_ = -1; | 
|   584   OSThread* os_thread = OSThread::Current(); |   584   OSThread* os_thread = OSThread::Current(); | 
|   585   ASSERT(os_thread != NULL); |   585   ASSERT(os_thread != NULL); | 
|   586   thread_ = os_thread->trace_id(); |   586   thread_ = os_thread->trace_id(); | 
|   587   Isolate* isolate = Isolate::Current(); |   587   Isolate* isolate = Isolate::Current(); | 
|   588   if (isolate != NULL) { |   588   if (isolate != NULL) { | 
|   589     isolate_id_ = isolate->main_port(); |   589     isolate_id_ = isolate->main_port(); | 
|   590   } else { |   590   } else { | 
|   591     isolate_id_ = ILLEGAL_PORT; |   591     isolate_id_ = ILLEGAL_PORT; | 
|   592   } |   592   } | 
|   593   label_ = label; |   593   label_ = label; | 
|   594   FreeArguments(); |   594   FreeArguments(); | 
|   595   set_pre_serialized_json(false); |   595   set_pre_serialized_json(false); | 
|   596   set_event_type(event_type); |   596   set_event_type(event_type); | 
|   597   set_owns_label(false); |   597   set_owns_label(false); | 
|   598 } |   598 } | 
|   599  |   599  | 
|   600  |   600  | 
|   601 bool TimelineEvent::Within(int64_t time_origin_micros, |   601 bool TimelineEvent::Within(int64_t time_origin_micros, | 
|   602                            int64_t time_extent_micros) { |   602                            int64_t time_extent_micros) { | 
|   603   if ((time_origin_micros == -1) || |   603   if ((time_origin_micros == -1) || (time_extent_micros == -1)) { | 
|   604       (time_extent_micros == -1)) { |  | 
|   605     // No time range specified. |   604     // No time range specified. | 
|   606     return true; |   605     return true; | 
|   607   } |   606   } | 
|   608   if (IsFinishedDuration()) { |   607   if (IsFinishedDuration()) { | 
|   609     // Event is from e_t0 to e_t1. |   608     // Event is from e_t0 to e_t1. | 
|   610     int64_t e_t0 = TimeOrigin(); |   609     int64_t e_t0 = TimeOrigin(); | 
|   611     int64_t e_t1 = TimeEnd(); |   610     int64_t e_t1 = TimeEnd(); | 
|   612     ASSERT(e_t0 <= e_t1); |   611     ASSERT(e_t0 <= e_t1); | 
|   613     // Range is from r_t0 to r_t1. |   612     // Range is from r_t0 to r_t1. | 
|   614     int64_t r_t0 = time_origin_micros; |   613     int64_t r_t0 = time_origin_micros; | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   646   obj.AddProperty("cat", category_); |   645   obj.AddProperty("cat", category_); | 
|   647   obj.AddProperty64("tid", tid); |   646   obj.AddProperty64("tid", tid); | 
|   648   obj.AddProperty64("pid", pid); |   647   obj.AddProperty64("pid", pid); | 
|   649   obj.AddPropertyTimeMicros("ts", TimeOrigin()); |   648   obj.AddPropertyTimeMicros("ts", TimeOrigin()); | 
|   650   if (HasThreadCPUTime()) { |   649   if (HasThreadCPUTime()) { | 
|   651     obj.AddPropertyTimeMicros("tts", ThreadCPUTimeOrigin()); |   650     obj.AddPropertyTimeMicros("tts", ThreadCPUTimeOrigin()); | 
|   652   } |   651   } | 
|   653   switch (event_type()) { |   652   switch (event_type()) { | 
|   654     case kBegin: { |   653     case kBegin: { | 
|   655       obj.AddProperty("ph", "B"); |   654       obj.AddProperty("ph", "B"); | 
|   656     } |   655     } break; | 
|   657     break; |  | 
|   658     case kEnd: { |   656     case kEnd: { | 
|   659       obj.AddProperty("ph", "E"); |   657       obj.AddProperty("ph", "E"); | 
|   660     } |   658     } break; | 
|   661     break; |  | 
|   662     case kDuration: { |   659     case kDuration: { | 
|   663       obj.AddProperty("ph", "X"); |   660       obj.AddProperty("ph", "X"); | 
|   664       obj.AddPropertyTimeMicros("dur", TimeDuration()); |   661       obj.AddPropertyTimeMicros("dur", TimeDuration()); | 
|   665       if (HasThreadCPUTime()) { |   662       if (HasThreadCPUTime()) { | 
|   666         obj.AddPropertyTimeMicros("tdur", ThreadCPUTimeDuration()); |   663         obj.AddPropertyTimeMicros("tdur", ThreadCPUTimeDuration()); | 
|   667       } |   664       } | 
|   668     } |   665     } break; | 
|   669     break; |  | 
|   670     case kInstant: { |   666     case kInstant: { | 
|   671       obj.AddProperty("ph", "i"); |   667       obj.AddProperty("ph", "i"); | 
|   672       obj.AddProperty("s", "p"); |   668       obj.AddProperty("s", "p"); | 
|   673     } |   669     } break; | 
|   674     break; |  | 
|   675     case kAsyncBegin: { |   670     case kAsyncBegin: { | 
|   676       obj.AddProperty("ph", "b"); |   671       obj.AddProperty("ph", "b"); | 
|   677       obj.AddPropertyF("id", "%" Px64 "", AsyncId()); |   672       obj.AddPropertyF("id", "%" Px64 "", AsyncId()); | 
|   678     } |   673     } break; | 
|   679     break; |  | 
|   680     case kAsyncInstant: { |   674     case kAsyncInstant: { | 
|   681       obj.AddProperty("ph", "n"); |   675       obj.AddProperty("ph", "n"); | 
|   682       obj.AddPropertyF("id", "%" Px64 "", AsyncId()); |   676       obj.AddPropertyF("id", "%" Px64 "", AsyncId()); | 
|   683     } |   677     } break; | 
|   684     break; |  | 
|   685     case kAsyncEnd: { |   678     case kAsyncEnd: { | 
|   686       obj.AddProperty("ph", "e"); |   679       obj.AddProperty("ph", "e"); | 
|   687       obj.AddPropertyF("id", "%" Px64 "", AsyncId()); |   680       obj.AddPropertyF("id", "%" Px64 "", AsyncId()); | 
|   688     } |   681     } break; | 
|   689     break; |  | 
|   690     case kMetadata: { |   682     case kMetadata: { | 
|   691       obj.AddProperty("ph", "M"); |   683       obj.AddProperty("ph", "M"); | 
|   692     } |   684     } break; | 
|   693     break; |  | 
|   694     case kCounter: { |   685     case kCounter: { | 
|   695       obj.AddProperty("ph", "C"); |   686       obj.AddProperty("ph", "C"); | 
|   696     } |   687     } break; | 
|   697     break; |  | 
|   698     default: |   688     default: | 
|   699       UNIMPLEMENTED(); |   689       UNIMPLEMENTED(); | 
|   700   } |   690   } | 
|   701   { |   691   { | 
|   702     JSONObject args(&obj, "args"); |   692     JSONObject args(&obj, "args"); | 
|   703     for (intptr_t i = 0; i < arguments_length_; i++) { |   693     for (intptr_t i = 0; i < arguments_length_; i++) { | 
|   704       const TimelineEventArgument& arg = arguments_[i]; |   694       const TimelineEventArgument& arg = arguments_[i]; | 
|   705       args.AddProperty(arg.name, arg.value); |   695       args.AddProperty(arg.name, arg.value); | 
|   706     } |   696     } | 
|   707     if (isolate_id_ != ILLEGAL_PORT) { |   697     if (isolate_id_ != ILLEGAL_PORT) { | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   744   } |   734   } | 
|   745   return timestamp1_ - timestamp0_; |   735   return timestamp1_ - timestamp0_; | 
|   746 } |   736 } | 
|   747  |   737  | 
|   748  |   738  | 
|   749 bool TimelineEvent::HasThreadCPUTime() const { |   739 bool TimelineEvent::HasThreadCPUTime() const { | 
|   750   return (thread_timestamp0_ != -1); |   740   return (thread_timestamp0_ != -1); | 
|   751 } |   741 } | 
|   752  |   742  | 
|   753  |   743  | 
|   754  |  | 
|   755 int64_t TimelineEvent::ThreadCPUTimeOrigin() const { |   744 int64_t TimelineEvent::ThreadCPUTimeOrigin() const { | 
|   756   ASSERT(HasThreadCPUTime()); |   745   ASSERT(HasThreadCPUTime()); | 
|   757   return thread_timestamp0_; |   746   return thread_timestamp0_; | 
|   758 } |   747 } | 
|   759  |   748  | 
|   760  |   749  | 
|   761 int64_t TimelineEvent::ThreadCPUTimeDuration() const { |   750 int64_t TimelineEvent::ThreadCPUTimeDuration() const { | 
|   762   ASSERT(HasThreadCPUTime()); |   751   ASSERT(HasThreadCPUTime()); | 
|   763   if (thread_timestamp1_ == -1) { |   752   if (thread_timestamp1_ == -1) { | 
|   764     // This duration is still open, use current time as end. |   753     // This duration is still open, use current time as end. | 
|   765     return OS::GetCurrentThreadCPUMicros() - thread_timestamp0_; |   754     return OS::GetCurrentThreadCPUMicros() - thread_timestamp0_; | 
|   766   } |   755   } | 
|   767   return thread_timestamp1_ - thread_timestamp0_; |   756   return thread_timestamp1_ - thread_timestamp0_; | 
|   768 } |   757 } | 
|   769  |   758  | 
|   770  |   759  | 
|   771 TimelineStream::TimelineStream() |   760 TimelineStream::TimelineStream() : name_(NULL), enabled_(false) {} | 
|   772     : name_(NULL), |  | 
|   773       enabled_(false) { |  | 
|   774 } |  | 
|   775  |   761  | 
|   776  |   762  | 
|   777 void TimelineStream::Init(const char* name, |   763 void TimelineStream::Init(const char* name, bool enabled) { | 
|   778                           bool enabled) { |  | 
|   779   name_ = name; |   764   name_ = name; | 
|   780   enabled_ = enabled; |   765   enabled_ = enabled; | 
|   781 } |   766 } | 
|   782  |   767  | 
|   783  |   768  | 
|   784 TimelineEvent* TimelineStream::StartEvent() { |   769 TimelineEvent* TimelineStream::StartEvent() { | 
|   785   TimelineEventRecorder* recorder = Timeline::recorder(); |   770   TimelineEventRecorder* recorder = Timeline::recorder(); | 
|   786   if (!enabled() || (recorder == NULL)) { |   771   if (!enabled() || (recorder == NULL)) { | 
|   787     return NULL; |   772     return NULL; | 
|   788   } |   773   } | 
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   872                                       const char* argument) { |   857                                       const char* argument) { | 
|   873   if (!enabled()) { |   858   if (!enabled()) { | 
|   874     return; |   859     return; | 
|   875   } |   860   } | 
|   876   SetArgument(i, name, strdup(argument)); |   861   SetArgument(i, name, strdup(argument)); | 
|   877 } |   862 } | 
|   878  |   863  | 
|   879  |   864  | 
|   880 void TimelineEventScope::FormatArgument(intptr_t i, |   865 void TimelineEventScope::FormatArgument(intptr_t i, | 
|   881                                         const char* name, |   866                                         const char* name, | 
|   882                                         const char* fmt, ...) { |   867                                         const char* fmt, | 
 |   868                                         ...) { | 
|   883   if (!enabled()) { |   869   if (!enabled()) { | 
|   884     return; |   870     return; | 
|   885   } |   871   } | 
|   886   va_list args; |   872   va_list args; | 
|   887   va_start(args, fmt); |   873   va_start(args, fmt); | 
|   888   intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |   874   intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); | 
|   889   va_end(args); |   875   va_end(args); | 
|   890  |   876  | 
|   891   char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |   877   char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 
|   892   va_list args2; |   878   va_list args2; | 
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   951   if (!ShouldEmitEvent()) { |   937   if (!ShouldEmitEvent()) { | 
|   952     return; |   938     return; | 
|   953   } |   939   } | 
|   954   TimelineEvent* event = stream()->StartEvent(); |   940   TimelineEvent* event = stream()->StartEvent(); | 
|   955   if (event == NULL) { |   941   if (event == NULL) { | 
|   956     // Stream is now disabled. |   942     // Stream is now disabled. | 
|   957     return; |   943     return; | 
|   958   } |   944   } | 
|   959   ASSERT(event != NULL); |   945   ASSERT(event != NULL); | 
|   960   // Emit a duration event. |   946   // Emit a duration event. | 
|   961   event->Duration(label(), |   947   event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), | 
|   962                   timestamp_, |   948                   thread_timestamp_, OS::GetCurrentThreadCPUMicros()); | 
|   963                   OS::GetCurrentMonotonicMicros(), |  | 
|   964                   thread_timestamp_, |  | 
|   965                   OS::GetCurrentThreadCPUMicros()); |  | 
|   966   StealArguments(event); |   949   StealArguments(event); | 
|   967   event->Complete(); |   950   event->Complete(); | 
|   968 } |   951 } | 
|   969  |   952  | 
|   970  |   953  | 
|   971 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, |   954 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, | 
|   972                                              const char* label) |   955                                              const char* label) | 
|   973     : TimelineEventScope(stream, label) { |   956     : TimelineEventScope(stream, label) { | 
|   974   if (!FLAG_support_timeline) { |   957   if (!FLAG_support_timeline) { | 
|   975     return; |   958     return; | 
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1040  |  1023  | 
|  1041 TimelineEventFilter::TimelineEventFilter(int64_t time_origin_micros, |  1024 TimelineEventFilter::TimelineEventFilter(int64_t time_origin_micros, | 
|  1042                                          int64_t time_extent_micros) |  1025                                          int64_t time_extent_micros) | 
|  1043     : time_origin_micros_(time_origin_micros), |  1026     : time_origin_micros_(time_origin_micros), | 
|  1044       time_extent_micros_(time_extent_micros) { |  1027       time_extent_micros_(time_extent_micros) { | 
|  1045   ASSERT(time_origin_micros_ >= -1); |  1028   ASSERT(time_origin_micros_ >= -1); | 
|  1046   ASSERT(time_extent_micros_ >= -1); |  1029   ASSERT(time_extent_micros_ >= -1); | 
|  1047 } |  1030 } | 
|  1048  |  1031  | 
|  1049  |  1032  | 
|  1050 TimelineEventFilter::~TimelineEventFilter() { |  1033 TimelineEventFilter::~TimelineEventFilter() {} | 
|  1051 } |  | 
|  1052  |  1034  | 
|  1053  |  1035  | 
|  1054 IsolateTimelineEventFilter::IsolateTimelineEventFilter( |  1036 IsolateTimelineEventFilter::IsolateTimelineEventFilter( | 
|  1055     Dart_Port isolate_id, |  1037     Dart_Port isolate_id, | 
|  1056     int64_t time_origin_micros, |  1038     int64_t time_origin_micros, | 
|  1057     int64_t time_extent_micros) |  1039     int64_t time_extent_micros) | 
|  1058     : TimelineEventFilter(time_origin_micros, |  1040     : TimelineEventFilter(time_origin_micros, time_extent_micros), | 
|  1059                           time_extent_micros), |  1041       isolate_id_(isolate_id) {} | 
|  1060       isolate_id_(isolate_id) { |  | 
|  1061 } |  | 
|  1062  |  1042  | 
|  1063  |  1043  | 
|  1064 TimelineEventRecorder::TimelineEventRecorder() |  1044 TimelineEventRecorder::TimelineEventRecorder() | 
|  1065     : async_id_(0), |  1045     : async_id_(0), time_low_micros_(0), time_high_micros_(0) {} | 
|  1066       time_low_micros_(0), |  | 
|  1067       time_high_micros_(0) { |  | 
|  1068 } |  | 
|  1069  |  1046  | 
|  1070  |  1047  | 
|  1071 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { |  1048 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { | 
|  1072   if (!FLAG_support_service) { |  1049   if (!FLAG_support_service) { | 
|  1073     return; |  1050     return; | 
|  1074   } |  1051   } | 
|  1075   OSThreadIterator it; |  1052   OSThreadIterator it; | 
|  1076   while (it.HasNext()) { |  1053   while (it.HasNext()) { | 
|  1077     OSThread* thread = it.Next(); |  1054     OSThread* thread = it.Next(); | 
|  1078     const char* thread_name = thread->name(); |  1055     const char* thread_name = thread->name(); | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1126     // Thread has no block. Attempt to allocate one. |  1103     // Thread has no block. Attempt to allocate one. | 
|  1127     thread_block = GetNewBlockLocked(); |  1104     thread_block = GetNewBlockLocked(); | 
|  1128     thread->set_timeline_block(thread_block); |  1105     thread->set_timeline_block(thread_block); | 
|  1129   } |  1106   } | 
|  1130   if (thread_block != NULL) { |  1107   if (thread_block != NULL) { | 
|  1131     // NOTE: We are exiting this function with the thread's block lock held. |  1108     // NOTE: We are exiting this function with the thread's block lock held. | 
|  1132     ASSERT(!thread_block->IsFull()); |  1109     ASSERT(!thread_block->IsFull()); | 
|  1133     TimelineEvent* event = thread_block->StartEvent(); |  1110     TimelineEvent* event = thread_block->StartEvent(); | 
|  1134     return event; |  1111     return event; | 
|  1135   } |  1112   } | 
|  1136   // Drop lock here as no event is being handed out. |  1113 // Drop lock here as no event is being handed out. | 
|  1137 #if defined(DEBUG) |  1114 #if defined(DEBUG) | 
|  1138   if (T != NULL) { |  1115   if (T != NULL) { | 
|  1139     T->DecrementNoSafepointScopeDepth(); |  1116     T->DecrementNoSafepointScopeDepth(); | 
|  1140   } |  1117   } | 
|  1141 #endif  // defined(DEBUG) |  1118 #endif  // defined(DEBUG) | 
|  1142   thread_block_lock->Unlock(); |  1119   thread_block_lock->Unlock(); | 
|  1143   return NULL; |  1120   return NULL; | 
|  1144 } |  1121 } | 
|  1145  |  1122  | 
|  1146  |  1123  | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1203   Dart_FileOpenCallback file_open = Dart::file_open_callback(); |  1180   Dart_FileOpenCallback file_open = Dart::file_open_callback(); | 
|  1204   Dart_FileWriteCallback file_write = Dart::file_write_callback(); |  1181   Dart_FileWriteCallback file_write = Dart::file_write_callback(); | 
|  1205   Dart_FileCloseCallback file_close = Dart::file_close_callback(); |  1182   Dart_FileCloseCallback file_close = Dart::file_close_callback(); | 
|  1206   if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { |  1183   if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { | 
|  1207     return; |  1184     return; | 
|  1208   } |  1185   } | 
|  1209  |  1186  | 
|  1210   Timeline::ReclaimCachedBlocksFromThreads(); |  1187   Timeline::ReclaimCachedBlocksFromThreads(); | 
|  1211  |  1188  | 
|  1212   intptr_t pid = OS::ProcessId(); |  1189   intptr_t pid = OS::ProcessId(); | 
|  1213   char* filename = OS::SCreate(NULL, |  1190   char* filename = | 
|  1214       "%s/dart-timeline-%" Pd ".json", directory, pid); |  1191       OS::SCreate(NULL, "%s/dart-timeline-%" Pd ".json", directory, pid); | 
|  1215   void* file = (*file_open)(filename, true); |  1192   void* file = (*file_open)(filename, true); | 
|  1216   if (file == NULL) { |  1193   if (file == NULL) { | 
|  1217     OS::Print("Failed to write timeline file: %s\n", filename); |  1194     OS::Print("Failed to write timeline file: %s\n", filename); | 
|  1218     free(filename); |  1195     free(filename); | 
|  1219     return; |  1196     return; | 
|  1220   } |  1197   } | 
|  1221   free(filename); |  1198   free(filename); | 
|  1222  |  1199  | 
|  1223   JSONStream js; |  1200   JSONStream js; | 
|  1224   TimelineEventFilter filter; |  1201   TimelineEventFilter filter; | 
|  1225   PrintTraceEvent(&js, &filter); |  1202   PrintTraceEvent(&js, &filter); | 
|  1226   // Steal output from JSONStream. |  1203   // Steal output from JSONStream. | 
|  1227   char* output = NULL; |  1204   char* output = NULL; | 
|  1228   intptr_t output_length = 0; |  1205   intptr_t output_length = 0; | 
|  1229   js.Steal(&output, &output_length); |  1206   js.Steal(&output, &output_length); | 
|  1230   (*file_write)(output, output_length, file); |  1207   (*file_write)(output, output_length, file); | 
|  1231   // Free the stolen output. |  1208   // Free the stolen output. | 
|  1232   free(output); |  1209   free(output); | 
|  1233   (*file_close)(file); |  1210   (*file_close)(file); | 
|  1234  |  1211  | 
|  1235   return; |  1212   return; | 
|  1236 } |  1213 } | 
|  1237  |  1214  | 
|  1238  |  1215  | 
|  1239 int64_t TimelineEventRecorder::GetNextAsyncId() { |  1216 int64_t TimelineEventRecorder::GetNextAsyncId() { | 
|  1240   // TODO(johnmccutchan): Gracefully handle wrap around. |  1217   // TODO(johnmccutchan): Gracefully handle wrap around. | 
|  1241   uint32_t next = static_cast<uint32_t>( |  1218   uint32_t next = | 
|  1242       AtomicOperations::FetchAndIncrement(&async_id_)); |  1219       static_cast<uint32_t>(AtomicOperations::FetchAndIncrement(&async_id_)); | 
|  1243   return static_cast<int64_t>(next); |  1220   return static_cast<int64_t>(next); | 
|  1244 } |  1221 } | 
|  1245  |  1222  | 
|  1246  |  1223  | 
|  1247 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { |  1224 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { | 
|  1248   if (block == NULL) { |  1225   if (block == NULL) { | 
|  1249     return; |  1226     return; | 
|  1250   } |  1227   } | 
|  1251   MutexLocker ml(&lock_); |  1228   MutexLocker ml(&lock_); | 
|  1252   block->Finish(); |  1229   block->Finish(); | 
|  1253 } |  1230 } | 
|  1254  |  1231  | 
|  1255  |  1232  | 
|  1256 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { |  1233 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { | 
|  1257   MutexLocker ml(&lock_); |  1234   MutexLocker ml(&lock_); | 
|  1258   return GetNewBlockLocked(); |  1235   return GetNewBlockLocked(); | 
|  1259 } |  1236 } | 
|  1260  |  1237  | 
|  1261  |  1238  | 
|  1262 TimelineEventFixedBufferRecorder::TimelineEventFixedBufferRecorder( |  1239 TimelineEventFixedBufferRecorder::TimelineEventFixedBufferRecorder( | 
|  1263     intptr_t capacity) |  1240     intptr_t capacity) | 
|  1264     : blocks_(NULL), |  1241     : blocks_(NULL), capacity_(capacity), num_blocks_(0), block_cursor_(0) { | 
|  1265       capacity_(capacity), |  | 
|  1266       num_blocks_(0), |  | 
|  1267       block_cursor_(0) { |  | 
|  1268   // Capacity must be a multiple of TimelineEventBlock::kBlockSize |  1242   // Capacity must be a multiple of TimelineEventBlock::kBlockSize | 
|  1269   ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); |  1243   ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); | 
|  1270   // Allocate blocks array. |  1244   // Allocate blocks array. | 
|  1271   num_blocks_ = capacity / TimelineEventBlock::kBlockSize; |  1245   num_blocks_ = capacity / TimelineEventBlock::kBlockSize; | 
|  1272   blocks_ = |  1246   blocks_ = reinterpret_cast<TimelineEventBlock**>( | 
|  1273       reinterpret_cast<TimelineEventBlock**>( |  1247       calloc(num_blocks_, sizeof(TimelineEventBlock*))); | 
|  1274           calloc(num_blocks_, sizeof(TimelineEventBlock*))); |  | 
|  1275   // Allocate each block. |  1248   // Allocate each block. | 
|  1276   for (intptr_t i = 0; i < num_blocks_; i++) { |  1249   for (intptr_t i = 0; i < num_blocks_; i++) { | 
|  1277     blocks_[i] = new TimelineEventBlock(i); |  1250     blocks_[i] = new TimelineEventBlock(i); | 
|  1278   } |  1251   } | 
|  1279   // Chain blocks together. |  1252   // Chain blocks together. | 
|  1280   for (intptr_t i = 0; i < num_blocks_ - 1; i++) { |  1253   for (intptr_t i = 0; i < num_blocks_ - 1; i++) { | 
|  1281     blocks_[i]->set_next(blocks_[i + 1]); |  1254     blocks_[i]->set_next(blocks_[i + 1]); | 
|  1282   } |  1255   } | 
|  1283 } |  1256 } | 
|  1284  |  1257  | 
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1394  |  1367  | 
|  1395 void TimelineEventFixedBufferRecorder::CompleteEvent(TimelineEvent* event) { |  1368 void TimelineEventFixedBufferRecorder::CompleteEvent(TimelineEvent* event) { | 
|  1396   if (event == NULL) { |  1369   if (event == NULL) { | 
|  1397     return; |  1370     return; | 
|  1398   } |  1371   } | 
|  1399   ThreadBlockCompleteEvent(event); |  1372   ThreadBlockCompleteEvent(event); | 
|  1400 } |  1373 } | 
|  1401  |  1374  | 
|  1402  |  1375  | 
|  1403 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) |  1376 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) | 
|  1404     : TimelineEventFixedBufferRecorder(capacity), |  1377     : TimelineEventFixedBufferRecorder(capacity), systrace_fd_(-1) { | 
|  1405       systrace_fd_(-1) { |  | 
|  1406 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) |  1378 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) | 
|  1407   const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; |  1379   const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; | 
|  1408   systrace_fd_ = open(kSystracePath, O_WRONLY); |  1380   systrace_fd_ = open(kSystracePath, O_WRONLY); | 
|  1409   if ((systrace_fd_ < 0) && FLAG_trace_timeline) { |  1381   if ((systrace_fd_ < 0) && FLAG_trace_timeline) { | 
|  1410     OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", |  1382     OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", | 
|  1411                  kSystracePath); |  1383                  kSystracePath); | 
|  1412   } |  1384   } | 
|  1413 #else |  1385 #else | 
|  1414   OS::PrintErr("Warning: The systrace timeline recorder is equivalent to the" |  1386   OS::PrintErr( | 
|  1415                "ring recorder on this platform."); |  1387       "Warning: The systrace timeline recorder is equivalent to the" | 
 |  1388       "ring recorder on this platform."); | 
|  1416 #endif |  1389 #endif | 
|  1417 } |  1390 } | 
|  1418  |  1391  | 
|  1419  |  1392  | 
|  1420 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { |  1393 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { | 
|  1421 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) |  1394 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) | 
|  1422   if (systrace_fd_ >= 0) { |  1395   if (systrace_fd_ >= 0) { | 
|  1423     close(systrace_fd_); |  1396     close(systrace_fd_); | 
|  1424   } |  1397   } | 
|  1425 #endif |  1398 #endif | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1480   if (block_cursor_ == num_blocks_) { |  1453   if (block_cursor_ == num_blocks_) { | 
|  1481     return NULL; |  1454     return NULL; | 
|  1482   } |  1455   } | 
|  1483   TimelineEventBlock* block = blocks_[block_cursor_++]; |  1456   TimelineEventBlock* block = blocks_[block_cursor_++]; | 
|  1484   block->Reset(); |  1457   block->Reset(); | 
|  1485   block->Open(); |  1458   block->Open(); | 
|  1486   return block; |  1459   return block; | 
|  1487 } |  1460 } | 
|  1488  |  1461  | 
|  1489  |  1462  | 
|  1490 TimelineEventCallbackRecorder::TimelineEventCallbackRecorder() { |  1463 TimelineEventCallbackRecorder::TimelineEventCallbackRecorder() {} | 
|  1491 } |  | 
|  1492  |  1464  | 
|  1493  |  1465  | 
|  1494 TimelineEventCallbackRecorder::~TimelineEventCallbackRecorder() { |  1466 TimelineEventCallbackRecorder::~TimelineEventCallbackRecorder() {} | 
|  1495 } |  | 
|  1496  |  1467  | 
|  1497  |  1468  | 
|  1498 void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js, |  1469 void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js, | 
|  1499                                                TimelineEventFilter* filter) { |  1470                                               TimelineEventFilter* filter) { | 
|  1500   if (!FLAG_support_service) { |  1471   if (!FLAG_support_service) { | 
|  1501     return; |  1472     return; | 
|  1502   } |  1473   } | 
|  1503   JSONObject topLevel(js); |  1474   JSONObject topLevel(js); | 
|  1504   topLevel.AddProperty("type", "_Timeline"); |  1475   topLevel.AddProperty("type", "_Timeline"); | 
|  1505   { |  1476   { | 
|  1506     JSONArray events(&topLevel, "traceEvents"); |  1477     JSONArray events(&topLevel, "traceEvents"); | 
|  1507     PrintJSONMeta(&events); |  1478     PrintJSONMeta(&events); | 
|  1508   } |  1479   } | 
|  1509 } |  1480 } | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  1525 } |  1496 } | 
|  1526  |  1497  | 
|  1527  |  1498  | 
|  1528 void TimelineEventCallbackRecorder::CompleteEvent(TimelineEvent* event) { |  1499 void TimelineEventCallbackRecorder::CompleteEvent(TimelineEvent* event) { | 
|  1529   OnEvent(event); |  1500   OnEvent(event); | 
|  1530   delete event; |  1501   delete event; | 
|  1531 } |  1502 } | 
|  1532  |  1503  | 
|  1533  |  1504  | 
|  1534 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() |  1505 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() | 
|  1535     : head_(NULL), |  1506     : head_(NULL), block_index_(0) {} | 
|  1536       block_index_(0) { |  | 
|  1537 } |  | 
|  1538  |  1507  | 
|  1539  |  1508  | 
|  1540 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js, |  1509 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js, | 
|  1541                                              TimelineEventFilter* filter) { |  1510                                              TimelineEventFilter* filter) { | 
|  1542   if (!FLAG_support_service) { |  1511   if (!FLAG_support_service) { | 
|  1543     return; |  1512     return; | 
|  1544   } |  1513   } | 
|  1545   JSONObject topLevel(js); |  1514   JSONObject topLevel(js); | 
|  1546   topLevel.AddProperty("type", "_Timeline"); |  1515   topLevel.AddProperty("type", "_Timeline"); | 
|  1547   { |  1516   { | 
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1655   OSThread* thread = OSThread::Current(); |  1624   OSThread* thread = OSThread::Current(); | 
|  1656   thread->set_timeline_block(NULL); |  1625   thread->set_timeline_block(NULL); | 
|  1657 } |  1626 } | 
|  1658  |  1627  | 
|  1659  |  1628  | 
|  1660 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) |  1629 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) | 
|  1661     : next_(NULL), |  1630     : next_(NULL), | 
|  1662       length_(0), |  1631       length_(0), | 
|  1663       block_index_(block_index), |  1632       block_index_(block_index), | 
|  1664       thread_id_(OSThread::kInvalidThreadId), |  1633       thread_id_(OSThread::kInvalidThreadId), | 
|  1665       in_use_(false) { |  1634       in_use_(false) {} | 
|  1666 } |  | 
|  1667  |  1635  | 
|  1668  |  1636  | 
|  1669 TimelineEventBlock::~TimelineEventBlock() { |  1637 TimelineEventBlock::~TimelineEventBlock() { | 
|  1670   Reset(); |  1638   Reset(); | 
|  1671 } |  1639 } | 
|  1672  |  1640  | 
|  1673  |  1641  | 
|  1674 void TimelineEventBlock::PrintJSON(JSONStream* js) const { |  1642 void TimelineEventBlock::PrintJSON(JSONStream* js) const { | 
|  1675   ASSERT(!in_use()); |  1643   ASSERT(!in_use()); | 
|  1676   JSONArray events(js); |  1644   JSONArray events(js); | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1753   if (Service::timeline_stream.enabled()) { |  1721   if (Service::timeline_stream.enabled()) { | 
|  1754     ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents); |  1722     ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents); | 
|  1755     service_event.set_timeline_event_block(this); |  1723     service_event.set_timeline_event_block(this); | 
|  1756     Service::HandleEvent(&service_event); |  1724     Service::HandleEvent(&service_event); | 
|  1757   } |  1725   } | 
|  1758 } |  1726 } | 
|  1759  |  1727  | 
|  1760  |  1728  | 
|  1761 TimelineEventBlockIterator::TimelineEventBlockIterator( |  1729 TimelineEventBlockIterator::TimelineEventBlockIterator( | 
|  1762     TimelineEventRecorder* recorder) |  1730     TimelineEventRecorder* recorder) | 
|  1763     : current_(NULL), |  1731     : current_(NULL), recorder_(NULL) { | 
|  1764       recorder_(NULL) { |  | 
|  1765   Reset(recorder); |  1732   Reset(recorder); | 
|  1766 } |  1733 } | 
|  1767  |  1734  | 
|  1768  |  1735  | 
|  1769 TimelineEventBlockIterator::~TimelineEventBlockIterator() { |  1736 TimelineEventBlockIterator::~TimelineEventBlockIterator() { | 
|  1770   Reset(NULL); |  1737   Reset(NULL); | 
|  1771 } |  1738 } | 
|  1772  |  1739  | 
|  1773  |  1740  | 
|  1774 void TimelineEventBlockIterator::Reset(TimelineEventRecorder* recorder) { |  1741 void TimelineEventBlockIterator::Reset(TimelineEventRecorder* recorder) { | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  1797 TimelineEventBlock* TimelineEventBlockIterator::Next() { |  1764 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 
|  1798   ASSERT(current_ != NULL); |  1765   ASSERT(current_ != NULL); | 
|  1799   TimelineEventBlock* r = current_; |  1766   TimelineEventBlock* r = current_; | 
|  1800   current_ = current_->next(); |  1767   current_ = current_->next(); | 
|  1801   return r; |  1768   return r; | 
|  1802 } |  1769 } | 
|  1803  |  1770  | 
|  1804 }  // namespace dart |  1771 }  // namespace dart | 
|  1805  |  1772  | 
|  1806 #endif  // !PRODUCT |  1773 #endif  // !PRODUCT | 
| OLD | NEW |