summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoshua Oreman2009-12-30 02:33:25 +0100
committerMarty Connor2010-01-14 17:30:30 +0100
commitdacc64724fda95d62b8b72b8c8b0010a7d6eda8b (patch)
tree37b34dea3943e9653ad4a460f931187466f12c1b
parent[makefile] Allow .sizes target to work with funny-named objects (diff)
downloadipxe-dacc64724fda95d62b8b72b8c8b0010a7d6eda8b.tar.gz
ipxe-dacc64724fda95d62b8b72b8c8b0010a7d6eda8b.tar.xz
ipxe-dacc64724fda95d62b8b72b8c8b0010a7d6eda8b.zip
[util] Add diffsize.pl utility for generating diffs of object sizes
This is useful when comparing size optimizations. Signed-off-by: Marty Connor <mdc@etherboot.org>
-rwxr-xr-xsrc/util/diffsize.pl101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/util/diffsize.pl b/src/util/diffsize.pl
new file mode 100755
index 00000000..d4978c2a
--- /dev/null
+++ b/src/util/diffsize.pl
@@ -0,0 +1,101 @@
+#!/usr/bin/perl -w
+# usage:
+# [somebody@somewhere ~/gpxe/src]$ ./util/diffsize.pl [<old rev> [<new rev>]]
+# by default <old rev> is HEAD and <new rev> is the working tree
+
+use strict;
+
+-d "bin" or die "Please run me in the gPXE src directory\n";
+mkdir ".sizes";
+
+my($oldrev, $newrev);
+my($oldname, $newname);
+
+if (@ARGV) {
+ $oldname = shift;
+} else {
+ $oldname = "HEAD";
+}
+
+if (@ARGV) {
+ $newname = shift;
+} else {
+ $newrev = "tree" . time();
+}
+
+$oldrev = `git rev-parse $oldname`;
+chomp $oldrev;
+
+unless (defined $newrev) {
+ $newrev = `git rev-parse $newname`;
+ chomp $newrev;
+}
+
+sub calc_sizes($$) {
+ my($name, $rev) = @_;
+ my $output;
+ my $lastrev;
+ my $stashed = 0;
+ my $res = 0;
+
+ return if -e ".sizes/$rev.sizes";
+
+ if (defined $name) {
+ $output = `git stash`;
+ $stashed = 1 unless $output =~ /No local changes to save/;
+ $lastrev = `git name-rev --name-only HEAD`;
+ system("git checkout $name >/dev/null"); $res ||= $?;
+ }
+
+ system("make -j4 bin/gpxe.lkrn >/dev/null"); $res ||= $?;
+ system("make bin/gpxe.lkrn.sizes > .sizes/$rev.sizes"); $res ||= $?;
+
+ if (defined $name) {
+ system("git checkout $lastrev >/dev/null"); $res ||= $?;
+ system("git stash pop >/dev/null") if $stashed; $res ||= $?;
+ }
+
+ if ($res) {
+ unlink(".sizes/$rev.sizes");
+ die "Error making sizes file\n";
+ }
+}
+
+our %Sizes;
+
+sub save_sizes($$) {
+ my($id, $rev) = @_;
+ my $file = ".sizes/$rev.sizes";
+
+ open SIZES, $file or die "opening $file: $!\n";
+ while (<SIZES>) {
+ my($text, $data, $bss, $total, $hex, $name) = split;
+ $name =~ s|bin/||; $name =~ s|\.o$||;
+
+ # Skip the header and totals lines
+ next if $total =~ /[a-z]/ or $name =~ /TOTALS/;
+
+ # Skip files named with dash, due to old Makefile bug
+ next if $name =~ /-/;
+
+ $Sizes{$name} = {old => 0, new => 0} unless exists $Sizes{$name};
+ $Sizes{$name}{$id} = $total;
+ }
+}
+
+calc_sizes($oldname, $oldrev);
+calc_sizes($newname, $newrev);
+
+save_sizes('old', $oldrev);
+save_sizes('new', $newrev);
+
+my $total = 0;
+
+for (sort keys %Sizes) {
+ my $diff = $Sizes{$_}{new} - $Sizes{$_}{old};
+ if (abs($diff) >= 16) {
+ printf "%12s %+d\n", substr($_, 0, 12), $Sizes{$_}{new} - $Sizes{$_}{old};
+ }
+ $total += $diff;
+}
+printf " TOTAL: %+d\n", $total;