1#!/usr/bin/perl -w
2# usage:
3# [somebody@somewhere ~/gpxe/src]$ ./util/diffsize.pl [<old rev> [<new rev>]]
4# by default <old rev> is HEAD and <new rev> is the working tree
5
6use strict;
7
8-d "bin" or die "Please run me in the gPXE src directory\n";
9mkdir ".sizes";
10
11my($oldrev, $newrev);
12my($oldname, $newname);
13
14if (@ARGV) {
15  $oldname = shift;
16} else {
17  $oldname = "HEAD";
18}
19
20if (@ARGV) {
21  $newname = shift;
22} else {
23  $newrev = "tree" . time();
24}
25
26$oldrev = `git rev-parse $oldname`;
27chomp $oldrev;
28
29unless (defined $newrev) {
30  $newrev = `git rev-parse $newname`;
31  chomp $newrev;
32}
33
34sub calc_sizes($$) {
35  my($name, $rev) = @_;
36  my $output;
37  my $lastrev;
38  my $stashed = 0;
39  my $res = 0;
40
41  return if -e ".sizes/$rev.sizes";
42
43  if (defined $name) {
44    $output = `git stash`;
45    $stashed = 1 unless $output =~ /No local changes to save/;
46    $lastrev = `git name-rev --name-only HEAD`;
47    system("git checkout $name >/dev/null"); $res ||= $?;
48  }
49
50  system("make -j4 bin/gpxe.lkrn >/dev/null"); $res ||= $?;
51  system("make bin/gpxe.lkrn.sizes > .sizes/$rev.sizes"); $res ||= $?;
52
53  if (defined $name) {
54    system("git checkout $lastrev >/dev/null"); $res ||= $?;
55    system("git stash pop >/dev/null") if $stashed; $res ||= $?;
56  }
57
58  if ($res) {
59    unlink(".sizes/$rev.sizes");
60    die "Error making sizes file\n";
61  }
62}
63
64our %Sizes;
65
66sub save_sizes($$) {
67  my($id, $rev) = @_;
68  my $file = ".sizes/$rev.sizes";
69
70  open SIZES, $file or die "opening $file: $!\n";
71  while (<SIZES>) {
72    my($text, $data, $bss, $total, $hex, $name) = split;
73    $name =~ s|bin/||; $name =~ s|\.o$||;
74
75    # Skip the header and totals lines
76    next if $total =~ /[a-z]/ or $name =~ /TOTALS/;
77
78    # Skip files named with dash, due to old Makefile bug
79    next if $name =~ /-/;
80
81    $Sizes{$name} = {old => 0, new => 0} unless exists $Sizes{$name};
82    $Sizes{$name}{$id} = $total;
83  }
84}
85
86calc_sizes($oldname, $oldrev);
87calc_sizes($newname, $newrev);
88
89save_sizes('old', $oldrev);
90save_sizes('new', $newrev);
91
92my $total = 0;
93
94for (sort keys %Sizes) {
95  my $diff = $Sizes{$_}{new} - $Sizes{$_}{old};
96  if (abs($diff) >= 16) {
97    printf "%12s %+d\n", substr($_, 0, 12), $Sizes{$_}{new} - $Sizes{$_}{old};
98  }
99  $total += $diff;
100}
101printf "      TOTAL: %+d\n", $total;
102