Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(548)

Side by Side Diff: runtime/vm/timeline_analysis.cc

Issue 1386263002: Add support to timeline for begin and end events (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/timeline_analysis.h ('k') | runtime/vm/timeline_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/timeline_analysis.h" 5 #include "vm/timeline_analysis.h"
6 6
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/log.h" 8 #include "vm/log.h"
9 #include "vm/os_thread.h" 9 #include "vm/os_thread.h"
10 10
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 192
193 193
194 void TimelineAnalysis::SetError(const char* format, ...) { 194 void TimelineAnalysis::SetError(const char* format, ...) {
195 ASSERT(!has_error_); 195 ASSERT(!has_error_);
196 ASSERT(error_msg_ == NULL); 196 ASSERT(error_msg_ == NULL);
197 has_error_ = true; 197 has_error_ = true;
198 va_list args; 198 va_list args;
199 va_start(args, format); 199 va_start(args, format);
200 error_msg_ = zone_->VPrint(format, args); 200 error_msg_ = zone_->VPrint(format, args);
201 ASSERT(error_msg_ != NULL); 201 ASSERT(error_msg_ != NULL);
202 if (FLAG_trace_timeline_analysis) {
203 OS::Print("TimelineAnalysis error = %s\n", error_msg_);
204 }
202 } 205 }
203 206
204 207
205 TimelineLabelPauseInfo::TimelineLabelPauseInfo(const char* name) 208 TimelineLabelPauseInfo::TimelineLabelPauseInfo(const char* name)
206 : name_(name), 209 : name_(name),
207 inclusive_micros_(0), 210 inclusive_micros_(0),
208 exclusive_micros_(0), 211 exclusive_micros_(0),
209 max_inclusive_micros_(0), 212 max_inclusive_micros_(0),
210 max_exclusive_micros_(0) { 213 max_exclusive_micros_(0) {
211 ASSERT(name_ != NULL); 214 ASSERT(name_ != NULL);
212 } 215 }
213 216
214 217
215 void TimelineLabelPauseInfo::OnPush(int64_t micros, bool already_on_stack) { 218 void TimelineLabelPauseInfo::OnPush(int64_t micros, bool already_on_stack) {
219 UpdateInclusiveMicros(micros, already_on_stack);
220 }
221
222
223 void TimelineLabelPauseInfo::OnPop(int64_t exclusive_micros) {
224 UpdateExclusiveMicros(exclusive_micros);
225 }
226
227
228 void TimelineLabelPauseInfo::OnBeginPop(int64_t inclusive_micros,
229 int64_t exclusive_micros,
230 bool already_on_stack) {
231 UpdateInclusiveMicros(inclusive_micros, already_on_stack);
232 UpdateExclusiveMicros(exclusive_micros);
233 }
234
235
236 void TimelineLabelPauseInfo::UpdateInclusiveMicros(int64_t inclusive_micros,
237 bool already_on_stack) {
216 if (!already_on_stack) { 238 if (!already_on_stack) {
217 // Only adjust inclusive counts if we aren't already on the stack. 239 // Only adjust inclusive counts if we aren't already on the stack.
218 add_inclusive_micros(micros); 240 add_inclusive_micros(inclusive_micros);
219 if (micros > max_inclusive_micros_) { 241 if (inclusive_micros > max_inclusive_micros_) {
220 max_inclusive_micros_ = micros; 242 max_inclusive_micros_ = inclusive_micros;
221 } 243 }
222 } 244 }
223 } 245 }
224 246
225 247
226 void TimelineLabelPauseInfo::OnPop(int64_t exclusive_micros) { 248 void TimelineLabelPauseInfo::UpdateExclusiveMicros(int64_t exclusive_micros) {
227 add_exclusive_micros(exclusive_micros); 249 add_exclusive_micros(exclusive_micros);
228 if (exclusive_micros > max_exclusive_micros_) { 250 if (exclusive_micros > max_exclusive_micros_) {
229 max_exclusive_micros_ = exclusive_micros; 251 max_exclusive_micros_ = exclusive_micros;
230 } 252 }
231 } 253 }
232 254
233 255
234 void TimelineLabelPauseInfo::Aggregate( 256 void TimelineLabelPauseInfo::Aggregate(
235 const TimelineLabelPauseInfo* thread_pause_info) { 257 const TimelineLabelPauseInfo* thread_pause_info) {
236 ASSERT(thread_pause_info != NULL); 258 ASSERT(thread_pause_info != NULL);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 ASSERT(thread != NULL); 338 ASSERT(thread != NULL);
317 stack_.Clear(); 339 stack_.Clear();
318 labels_.Clear(); 340 labels_.Clear();
319 341
320 TimelineAnalysisThreadEventIterator it(thread); 342 TimelineAnalysisThreadEventIterator it(thread);
321 if (FLAG_trace_timeline_analysis) { 343 if (FLAG_trace_timeline_analysis) {
322 THR_Print(">>> TimelinePauses::ProcessThread %" Px "\n", 344 THR_Print(">>> TimelinePauses::ProcessThread %" Px "\n",
323 OSThread::ThreadIdToIntPtr(thread->id())); 345 OSThread::ThreadIdToIntPtr(thread->id()));
324 } 346 }
325 intptr_t event_count = 0; 347 intptr_t event_count = 0;
326 while (it.HasNext()) { 348 while (!has_error() && it.HasNext()) {
327 TimelineEvent* event = it.Next(); 349 TimelineEvent* event = it.Next();
328 if (!event->IsFinishedDuration()) { 350 if (event->IsFinishedDuration()) {
329 // We only care about finished duration events. 351 int64_t start = event->TimeOrigin();
330 continue; 352 PopFinishedDurations(start);
353 if (!CheckStack(event)) {
354 SetError("Duration check fail.");
355 return;
356 }
357 event_count++;
358 Push(event);
359 } else if (event->IsBeginOrEnd()) {
360 event_count++;
361 if (event->IsBegin()) {
362 PopFinishedDurations(event->TimeOrigin());
363 Push(event);
364 } else {
365 ASSERT(event->IsEnd());
366 PopFinishedDurations(event->TimeOrigin());
367 PopBegin(event->label(), event->TimeOrigin());
368 }
369 } else {
370 // Skip other event kinds.
331 } 371 }
332 int64_t start = event->TimeOrigin();
333 PopFinished(start);
334 if (!CheckStack(event)) {
335 SetError("Duration check fail.");
336 return;
337 }
338 event_count++;
339 Push(event);
340 } 372 }
341 // Pop remaining stack. 373 // Pop remaining duration stack.
342 PopFinished(kMaxInt64); 374 PopFinishedDurations(kMaxInt64);
343 if (FLAG_trace_timeline_analysis) { 375 if (FLAG_trace_timeline_analysis) {
344 THR_Print("<<< TimelinePauses::ProcessThread %" Px " had %" Pd " events\n", 376 THR_Print("<<< TimelinePauses::ProcessThread %" Px " had %" Pd " events\n",
345 OSThread::ThreadIdToIntPtr(thread->id()), 377 OSThread::ThreadIdToIntPtr(thread->id()),
346 event_count); 378 event_count);
347 } 379 }
348 } 380 }
349 381
350 382
351 // Verify that |event| is contained within all parent events on the stack. 383 // Verify that |event| is contained within all parent events on the stack.
352 bool TimelinePauses::CheckStack(TimelineEvent* event) { 384 bool TimelinePauses::CheckStack(TimelineEvent* event) {
353 ASSERT(event != NULL); 385 ASSERT(event != NULL);
354 for (intptr_t i = 0; i < stack_.length(); i++) { 386 for (intptr_t i = 0; i < stack_.length(); i++) {
355 const StackItem& slot = stack_.At(i); 387 const StackItem& slot = stack_.At(i);
356 if (!slot.event->DurationContains(event)) { 388 if (slot.event->IsDuration()) {
357 return false; 389 if (!slot.event->DurationContains(event)) {
390 return false;
391 }
392 } else {
393 ASSERT(slot.event->IsBegin());
394 if (slot.event->TimeOrigin() > event->TimeOrigin()) {
395 return false;
396 }
358 } 397 }
359 } 398 }
360 return true; 399 return true;
361 } 400 }
362 401
363 402
364 void TimelinePauses::PopFinished(int64_t start) { 403 void TimelinePauses::PopFinishedDurations(int64_t start) {
365 while (stack_.length() > 0) { 404 while (stack_.length() > 0) {
366 const StackItem& top = stack_.Last(); 405 const StackItem& top = stack_.Last();
367 if (top.event->DurationFinishedBefore(start)) { 406 if (top.event->IsDuration() && top.event->DurationFinishedBefore(start)) {
368 top.pause_info->OnPop(top.exclusive_micros); 407 top.pause_info->OnPop(top.exclusive_micros);
369 // Top of stack completes before |start|. 408 // Top of stack completes before |start|.
370 stack_.RemoveLast(); 409 stack_.RemoveLast();
371 if (FLAG_trace_timeline_analysis) { 410 if (FLAG_trace_timeline_analysis) {
372 THR_Print("Popping %s (%" Pd64 " <= %" Pd64 ")\n", 411 THR_Print("Popping %s (%" Pd64 " <= %" Pd64 ")\n",
373 top.event->label(), 412 top.event->label(),
374 top.event->TimeEnd(), 413 top.event->TimeEnd(),
375 start); 414 start);
376 } 415 }
377 } else { 416 } else {
378 return; 417 return;
379 } 418 }
380 } 419 }
381 } 420 }
382 421
383 422
423 void TimelinePauses::PopBegin(const char* label, int64_t end) {
424 if (stack_.length() == 0) {
425 SetError("PopBegin(%s, ...) called with empty stack.", label);
426 return;
427 }
428 ASSERT(stack_.length() > 0);
429 const StackItem& top = stack_.Last();
430 const char* top_label = top.event->label();
431 const bool top_is_begin = top.event->IsBegin();
432 const int64_t start = top.event->TimeOrigin();
433 if (start > end) {
434 SetError("Bad time stamps for PopBegin(%s, ...) %" Pd64 " > %" Pd64 "",
435 label, start, end);
436 return;
437 }
438 const int64_t duration = end - start;
439 // Sanity checks.
440 if (strcmp(top_label, label) != 0) {
441 SetError("PopBegin(%s, ...) called with %s at the top of stack",
442 label, top.event->label());
443 return;
444 }
445 if (!top_is_begin) {
446 SetError("kEnd event not paired with kBegin event for label %s",
447 label);
448 return;
449 }
450 // Pop this event.
451 // Add duration to exclusive micros.
452 if (FLAG_trace_timeline_analysis) {
453 THR_Print("Popping %s (%" Pd64 ")\n",
454 top.event->label(),
455 duration);
456 }
457 const int64_t exclusive_micros = top.exclusive_micros + duration;
458 stack_.RemoveLast();
459 top.pause_info->OnBeginPop(duration,
460 exclusive_micros,
461 IsLabelOnStack(top_label));
462 if (StackDepth() > 0) {
463 StackItem& top = GetStackTop();
464 // |top| is under the popped |event|'s shadow, adjust the exclusive micros.
465 top.exclusive_micros -= duration;
466 }
467 }
468
469
384 void TimelinePauses::Push(TimelineEvent* event) { 470 void TimelinePauses::Push(TimelineEvent* event) {
385 TimelineLabelPauseInfo* pause_info = GetOrAddLabelPauseInfo(event->label()); 471 TimelineLabelPauseInfo* pause_info = GetOrAddLabelPauseInfo(event->label());
386 ASSERT(pause_info != NULL); 472 ASSERT(pause_info != NULL);
387 // |pause_info| will be running for |event->TimeDuration()|. 473 // |pause_info| will be running for |event->TimeDuration()|.
388 if (FLAG_trace_timeline_analysis) { 474 if (FLAG_trace_timeline_analysis) {
389 THR_Print("Pushing %s %" Pd64 " us\n", 475 THR_Print("Pushing %s %" Pd64 " us\n",
390 pause_info->name(), 476 pause_info->name(),
391 event->TimeDuration()); 477 event->TimeDuration());
392 } 478 }
393 pause_info->OnPush(event->TimeDuration(), IsLabelOnStack(event->label())); 479 if (event->IsDuration()) {
394 if (StackDepth() > 0) { 480 pause_info->OnPush(event->TimeDuration(), IsLabelOnStack(event->label()));
395 StackItem& top = GetStackTop(); 481 if (StackDepth() > 0) {
396 // |top| is under |event|'s shadow, adjust the exclusive micros. 482 StackItem& top = GetStackTop();
397 top.exclusive_micros -= event->TimeDuration(); 483 // |top| is under |event|'s shadow, adjust the exclusive micros.
484 top.exclusive_micros -= event->TimeDuration();
485 }
486 // Push onto the stack.
487 StackItem item;
488 item.event = event;
489 item.pause_info = pause_info;
490 item.exclusive_micros = event->TimeDuration();
491 stack_.Add(item);
492 } else {
493 ASSERT(event->IsBegin());
494 pause_info->OnPush(0, IsLabelOnStack(event->label()));
495 // Push onto the stack.
496 StackItem item;
497 item.event = event;
498 item.pause_info = pause_info;
499 item.exclusive_micros = 0;
500 stack_.Add(item);
398 } 501 }
399 // Push onto the stack.
400 StackItem item;
401 item.event = event;
402 item.pause_info = pause_info;
403 item.exclusive_micros = event->TimeDuration();
404 stack_.Add(item);
405 } 502 }
406 503
407 504
408 bool TimelinePauses::IsLabelOnStack(const char* label) const { 505 bool TimelinePauses::IsLabelOnStack(const char* label) const {
409 ASSERT(label != NULL); 506 ASSERT(label != NULL);
410 for (intptr_t i = 0; i < stack_.length(); i++) { 507 for (intptr_t i = 0; i < stack_.length(); i++) {
411 const StackItem& slot = stack_.At(i); 508 const StackItem& slot = stack_.At(i);
412 if (strcmp(slot.event->label(), label) == 0) { 509 if (strcmp(slot.event->label(), label) == 0) {
413 return true; 510 return true;
414 } 511 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 MicrosecondsToMilliseconds(pause_info->inclusive_micros())); 623 MicrosecondsToMilliseconds(pause_info->inclusive_micros()));
527 THR_Print("%.3f ms total executing; ", 624 THR_Print("%.3f ms total executing; ",
528 MicrosecondsToMilliseconds(pause_info->exclusive_micros())); 625 MicrosecondsToMilliseconds(pause_info->exclusive_micros()));
529 THR_Print("%.3f ms max on stack; ", 626 THR_Print("%.3f ms max on stack; ",
530 MicrosecondsToMilliseconds(pause_info->max_inclusive_micros())); 627 MicrosecondsToMilliseconds(pause_info->max_inclusive_micros()));
531 THR_Print("%.3f ms max executing.\n", 628 THR_Print("%.3f ms max executing.\n",
532 MicrosecondsToMilliseconds(pause_info->max_exclusive_micros())); 629 MicrosecondsToMilliseconds(pause_info->max_exclusive_micros()));
533 } 630 }
534 631
535 } // namespace dart 632 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/timeline_analysis.h ('k') | runtime/vm/timeline_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698