| 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 |