diff options
Diffstat (limited to 'tools/perf/util/sort.c')
-rw-r--r-- | tools/perf/util/sort.c | 102 |
1 files changed, 76 insertions, 26 deletions
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 4906cd81cb56..9402885a77f3 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -373,6 +373,9 @@ struct sort_entry sort_cpu = { | |||
373 | static int64_t | 373 | static int64_t |
374 | sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right) | 374 | sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right) |
375 | { | 375 | { |
376 | if (!left->branch_info || !right->branch_info) | ||
377 | return cmp_null(left->branch_info, right->branch_info); | ||
378 | |||
376 | return _sort__dso_cmp(left->branch_info->from.map, | 379 | return _sort__dso_cmp(left->branch_info->from.map, |
377 | right->branch_info->from.map); | 380 | right->branch_info->from.map); |
378 | } | 381 | } |
@@ -380,13 +383,19 @@ sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right) | |||
380 | static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf, | 383 | static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf, |
381 | size_t size, unsigned int width) | 384 | size_t size, unsigned int width) |
382 | { | 385 | { |
383 | return _hist_entry__dso_snprintf(he->branch_info->from.map, | 386 | if (he->branch_info) |
384 | bf, size, width); | 387 | return _hist_entry__dso_snprintf(he->branch_info->from.map, |
388 | bf, size, width); | ||
389 | else | ||
390 | return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); | ||
385 | } | 391 | } |
386 | 392 | ||
387 | static int64_t | 393 | static int64_t |
388 | sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right) | 394 | sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right) |
389 | { | 395 | { |
396 | if (!left->branch_info || !right->branch_info) | ||
397 | return cmp_null(left->branch_info, right->branch_info); | ||
398 | |||
390 | return _sort__dso_cmp(left->branch_info->to.map, | 399 | return _sort__dso_cmp(left->branch_info->to.map, |
391 | right->branch_info->to.map); | 400 | right->branch_info->to.map); |
392 | } | 401 | } |
@@ -394,8 +403,11 @@ sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right) | |||
394 | static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf, | 403 | static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf, |
395 | size_t size, unsigned int width) | 404 | size_t size, unsigned int width) |
396 | { | 405 | { |
397 | return _hist_entry__dso_snprintf(he->branch_info->to.map, | 406 | if (he->branch_info) |
398 | bf, size, width); | 407 | return _hist_entry__dso_snprintf(he->branch_info->to.map, |
408 | bf, size, width); | ||
409 | else | ||
410 | return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); | ||
399 | } | 411 | } |
400 | 412 | ||
401 | static int64_t | 413 | static int64_t |
@@ -404,6 +416,12 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right) | |||
404 | struct addr_map_symbol *from_l = &left->branch_info->from; | 416 | struct addr_map_symbol *from_l = &left->branch_info->from; |
405 | struct addr_map_symbol *from_r = &right->branch_info->from; | 417 | struct addr_map_symbol *from_r = &right->branch_info->from; |
406 | 418 | ||
419 | if (!left->branch_info || !right->branch_info) | ||
420 | return cmp_null(left->branch_info, right->branch_info); | ||
421 | |||
422 | from_l = &left->branch_info->from; | ||
423 | from_r = &right->branch_info->from; | ||
424 | |||
407 | if (!from_l->sym && !from_r->sym) | 425 | if (!from_l->sym && !from_r->sym) |
408 | return _sort__addr_cmp(from_l->addr, from_r->addr); | 426 | return _sort__addr_cmp(from_l->addr, from_r->addr); |
409 | 427 | ||
@@ -413,8 +431,13 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right) | |||
413 | static int64_t | 431 | static int64_t |
414 | sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right) | 432 | sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right) |
415 | { | 433 | { |
416 | struct addr_map_symbol *to_l = &left->branch_info->to; | 434 | struct addr_map_symbol *to_l, *to_r; |
417 | struct addr_map_symbol *to_r = &right->branch_info->to; | 435 | |
436 | if (!left->branch_info || !right->branch_info) | ||
437 | return cmp_null(left->branch_info, right->branch_info); | ||
438 | |||
439 | to_l = &left->branch_info->to; | ||
440 | to_r = &right->branch_info->to; | ||
418 | 441 | ||
419 | if (!to_l->sym && !to_r->sym) | 442 | if (!to_l->sym && !to_r->sym) |
420 | return _sort__addr_cmp(to_l->addr, to_r->addr); | 443 | return _sort__addr_cmp(to_l->addr, to_r->addr); |
@@ -425,19 +448,27 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right) | |||
425 | static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf, | 448 | static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf, |
426 | size_t size, unsigned int width) | 449 | size_t size, unsigned int width) |
427 | { | 450 | { |
428 | struct addr_map_symbol *from = &he->branch_info->from; | 451 | if (he->branch_info) { |
429 | return _hist_entry__sym_snprintf(from->map, from->sym, from->addr, | 452 | struct addr_map_symbol *from = &he->branch_info->from; |
430 | he->level, bf, size, width); | ||
431 | 453 | ||
454 | return _hist_entry__sym_snprintf(from->map, from->sym, from->addr, | ||
455 | he->level, bf, size, width); | ||
456 | } | ||
457 | |||
458 | return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); | ||
432 | } | 459 | } |
433 | 460 | ||
434 | static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf, | 461 | static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf, |
435 | size_t size, unsigned int width) | 462 | size_t size, unsigned int width) |
436 | { | 463 | { |
437 | struct addr_map_symbol *to = &he->branch_info->to; | 464 | if (he->branch_info) { |
438 | return _hist_entry__sym_snprintf(to->map, to->sym, to->addr, | 465 | struct addr_map_symbol *to = &he->branch_info->to; |
439 | he->level, bf, size, width); | ||
440 | 466 | ||
467 | return _hist_entry__sym_snprintf(to->map, to->sym, to->addr, | ||
468 | he->level, bf, size, width); | ||
469 | } | ||
470 | |||
471 | return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); | ||
441 | } | 472 | } |
442 | 473 | ||
443 | struct sort_entry sort_dso_from = { | 474 | struct sort_entry sort_dso_from = { |
@@ -471,11 +502,13 @@ struct sort_entry sort_sym_to = { | |||
471 | static int64_t | 502 | static int64_t |
472 | sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right) | 503 | sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right) |
473 | { | 504 | { |
474 | const unsigned char mp = left->branch_info->flags.mispred != | 505 | unsigned char mp, p; |
475 | right->branch_info->flags.mispred; | 506 | |
476 | const unsigned char p = left->branch_info->flags.predicted != | 507 | if (!left->branch_info || !right->branch_info) |
477 | right->branch_info->flags.predicted; | 508 | return cmp_null(left->branch_info, right->branch_info); |
478 | 509 | ||
510 | mp = left->branch_info->flags.mispred != right->branch_info->flags.mispred; | ||
511 | p = left->branch_info->flags.predicted != right->branch_info->flags.predicted; | ||
479 | return mp || p; | 512 | return mp || p; |
480 | } | 513 | } |
481 | 514 | ||
@@ -483,10 +516,12 @@ static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf, | |||
483 | size_t size, unsigned int width){ | 516 | size_t size, unsigned int width){ |
484 | static const char *out = "N/A"; | 517 | static const char *out = "N/A"; |
485 | 518 | ||
486 | if (he->branch_info->flags.predicted) | 519 | if (he->branch_info) { |
487 | out = "N"; | 520 | if (he->branch_info->flags.predicted) |
488 | else if (he->branch_info->flags.mispred) | 521 | out = "N"; |
489 | out = "Y"; | 522 | else if (he->branch_info->flags.mispred) |
523 | out = "Y"; | ||
524 | } | ||
490 | 525 | ||
491 | return repsep_snprintf(bf, size, "%-*.*s", width, width, out); | 526 | return repsep_snprintf(bf, size, "%-*.*s", width, width, out); |
492 | } | 527 | } |
@@ -989,6 +1024,9 @@ struct sort_entry sort_mem_dcacheline = { | |||
989 | static int64_t | 1024 | static int64_t |
990 | sort__abort_cmp(struct hist_entry *left, struct hist_entry *right) | 1025 | sort__abort_cmp(struct hist_entry *left, struct hist_entry *right) |
991 | { | 1026 | { |
1027 | if (!left->branch_info || !right->branch_info) | ||
1028 | return cmp_null(left->branch_info, right->branch_info); | ||
1029 | |||
992 | return left->branch_info->flags.abort != | 1030 | return left->branch_info->flags.abort != |
993 | right->branch_info->flags.abort; | 1031 | right->branch_info->flags.abort; |
994 | } | 1032 | } |
@@ -996,10 +1034,15 @@ sort__abort_cmp(struct hist_entry *left, struct hist_entry *right) | |||
996 | static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf, | 1034 | static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf, |
997 | size_t size, unsigned int width) | 1035 | size_t size, unsigned int width) |
998 | { | 1036 | { |
999 | static const char *out = "."; | 1037 | static const char *out = "N/A"; |
1038 | |||
1039 | if (he->branch_info) { | ||
1040 | if (he->branch_info->flags.abort) | ||
1041 | out = "A"; | ||
1042 | else | ||
1043 | out = "."; | ||
1044 | } | ||
1000 | 1045 | ||
1001 | if (he->branch_info->flags.abort) | ||
1002 | out = "A"; | ||
1003 | return repsep_snprintf(bf, size, "%-*s", width, out); | 1046 | return repsep_snprintf(bf, size, "%-*s", width, out); |
1004 | } | 1047 | } |
1005 | 1048 | ||
@@ -1013,6 +1056,9 @@ struct sort_entry sort_abort = { | |||
1013 | static int64_t | 1056 | static int64_t |
1014 | sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right) | 1057 | sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right) |
1015 | { | 1058 | { |
1059 | if (!left->branch_info || !right->branch_info) | ||
1060 | return cmp_null(left->branch_info, right->branch_info); | ||
1061 | |||
1016 | return left->branch_info->flags.in_tx != | 1062 | return left->branch_info->flags.in_tx != |
1017 | right->branch_info->flags.in_tx; | 1063 | right->branch_info->flags.in_tx; |
1018 | } | 1064 | } |
@@ -1020,10 +1066,14 @@ sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right) | |||
1020 | static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf, | 1066 | static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf, |
1021 | size_t size, unsigned int width) | 1067 | size_t size, unsigned int width) |
1022 | { | 1068 | { |
1023 | static const char *out = "."; | 1069 | static const char *out = "N/A"; |
1024 | 1070 | ||
1025 | if (he->branch_info->flags.in_tx) | 1071 | if (he->branch_info) { |
1026 | out = "T"; | 1072 | if (he->branch_info->flags.in_tx) |
1073 | out = "T"; | ||
1074 | else | ||
1075 | out = "."; | ||
1076 | } | ||
1027 | 1077 | ||
1028 | return repsep_snprintf(bf, size, "%-*s", width, out); | 1078 | return repsep_snprintf(bf, size, "%-*s", width, out); |
1029 | } | 1079 | } |