stackdelta 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #!/usr/bin/env perl
  2. # SPDX-License-Identifier: GPL-2.0
  3. # Read two files produced by the stackusage script, and show the
  4. # delta between them.
  5. #
  6. # Currently, only shows changes for functions listed in both files. We
  7. # could add an option to show also functions which have vanished or
  8. # appeared (which would often be due to gcc making other inlining
  9. # decisions).
  10. #
  11. # Another possible option would be a minimum absolute value for the
  12. # delta.
  13. #
  14. # A third possibility is for sorting by delta, but that can be
  15. # achieved by piping to sort -k5,5g.
  16. sub read_stack_usage_file {
  17. my %su;
  18. my $f = shift;
  19. open(my $fh, '<', $f)
  20. or die "cannot open $f: $!";
  21. while (<$fh>) {
  22. chomp;
  23. my ($file, $func, $size, $type) = split;
  24. # Old versions of gcc (at least 4.7) have an annoying quirk in
  25. # that a (static) function whose name has been changed into
  26. # for example ext4_find_unwritten_pgoff.isra.11 will show up
  27. # in the .su file with a name of just "11". Since such a
  28. # numeric suffix is likely to change across different
  29. # commits/compilers/.configs or whatever else we're trying to
  30. # tweak, we can't really track those functions, so we just
  31. # silently skip them.
  32. #
  33. # Newer gcc (at least 5.0) report the full name, so again,
  34. # since the suffix is likely to change, we strip it.
  35. next if $func =~ m/^[0-9]+$/;
  36. $func =~ s/\..*$//;
  37. # Line numbers are likely to change; strip those.
  38. $file =~ s/:[0-9]+$//;
  39. $su{"${file}\t${func}"} = {size => $size, type => $type};
  40. }
  41. close($fh);
  42. return \%su;
  43. }
  44. @ARGV == 2
  45. or die "usage: $0 <old> <new>";
  46. my $old = read_stack_usage_file($ARGV[0]);
  47. my $new = read_stack_usage_file($ARGV[1]);
  48. my @common = sort grep {exists $new->{$_}} keys %$old;
  49. for (@common) {
  50. my $x = $old->{$_}{size};
  51. my $y = $new->{$_}{size};
  52. my $delta = $y - $x;
  53. if ($delta) {
  54. printf "%s\t%d\t%d\t%+d\n", $_, $x, $y, $delta;
  55. }
  56. }