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