aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/bloat-o-meter72
1 files changed, 46 insertions, 26 deletions
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter
index eb6fb87d5..aa126969c 100755
--- a/scripts/bloat-o-meter
+++ b/scripts/bloat-o-meter
@@ -21,51 +21,68 @@ for f in sys.argv[1:3]:
21 sys.stderr.write("Error: file '%s' does not exist\n" % f) 21 sys.stderr.write("Error: file '%s' does not exist\n" % f)
22 usage() 22 usage()
23 23
24nm_args = " ".join(sys.argv[3:]) 24sym_args = " ".join(sys.argv[3:])
25def getsizes(file): 25def getsizes(file):
26 sym = {} 26 sym, alias = {}, {}
27 for l in os.popen("nm --size-sort %s %s" % (nm_args, file)).readlines(): 27 dynsym_filter = re.compile("^\s+\d+:\s+[\dA-Fa-f]+\s+\d+\s+\w+\s+\w+\s+\w+\s+\w+\s+\w+\n$")
28 l = l.strip() 28 for l in os.popen("readelf -W -s %s %s" % (sym_args, file)).readlines():
29 # Skip empty lines 29 if not dynsym_filter.match(l): continue
30 if not len(l): continue 30 num, value, size, typ, bind, vis, ndx, name = l.strip().split()
31 # Skip archive members 31 if ndx == "UND": continue # skip undefined
32 if len(l.split()) == 1 and l.endswith(':'): 32 if typ in ["SECTION", "FILES"]: continue # skip sections and files
33 continue 33 if "." in name: name = "static." + name.split(".")[0]
34 size, type, name = l.split() 34 value = int(value, 16)
35 if type in "tTdDbBrR": 35 size = int(size)
36 if "." in name: name = "static." + name.split(".")[0] 36 if bind != "GLOBAL": # see if it is an alias
37 sym[name] = sym.get(name, 0) + int(size, 16) 37 alias[name] = {"addr" : value, "size": size}
38 for l in os.popen("readelf -S " + file).readlines(): 38 else:
39 sym[name] = {"addr" : value, "size": size}
40 for a_nam, a_dat in alias.iteritems():
41 impl = [k for k, v in sym.iteritems() if v.get("addr") == a_dat["addr"]]
42 # If the non-GLOBAL sym has an implementation elsewhere then
43 # it's an alias, disregard it.
44 if not impl:
45 # If this non-GLOBAL sym does not have an implementation at
46 # another address, then treat it as a normal symbol.
47 sym[a_nam] = a_dat
48 for l in os.popen("readelf -W -S " + file).readlines():
39 x = l.split() 49 x = l.split()
40 if len(x)<6 or x[1] != ".rodata": continue 50 if len(x)<6: continue
41 sym[".rodata"] = int(x[5], 16) 51 # Should take these into account too!
52 #if x[1] not in [".text", ".rodata", ".symtab", ".strtab"]: continue
53 if x[1] not in [".rodata"]: continue
54 sym[x[1]] = {"addr" : int(x[3], 16), "size" : int(x[5], 16)}
42 return sym 55 return sym
43 56
44old = getsizes(sys.argv[1]) 57old = getsizes(sys.argv[1])
45new = getsizes(sys.argv[2]) 58new = getsizes(sys.argv[2])
46grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0 59grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
47delta, common = [], {} 60delta, common = [], []
48 61
49for a in old: 62for a in old.iterkeys():
50 if a in new: 63 if a in new:
51 common[a] = 1 64 common.append(a)
52 65
53for name in old: 66for name in old:
54 if name not in common: 67 if name not in common:
55 remove += 1 68 remove += 1
56 down += old[name] 69 sz = old[name].get("size", 0)
57 delta.append((-old[name], name)) 70 down += sz
71 delta.append((-sz, name))
58 72
59for name in new: 73for name in new:
60 if name not in common: 74 if name not in common:
61 add += 1 75 add += 1
62 up += new[name] 76 sz = new[name].get("size", 0)
63 delta.append((new[name], name)) 77 up += sz
78 delta.append((sz, name))
64 79
65for name in common: 80for name in common:
66 d = new.get(name, 0) - old.get(name, 0) 81 d = new[name].get("size", 0) - old[name].get("size", 0)
67 if d>0: grow, up = grow+1, up+d 82 if d>0: grow, up = grow+1, up+d
68 if d<0: shrink, down = shrink+1, down-d 83 elif d<0: shrink, down = shrink+1, down-d
84 else:
85 continue
69 delta.append((d, name)) 86 delta.append((d, name))
70 87
71delta.sort() 88delta.sort()
@@ -73,7 +90,10 @@ delta.reverse()
73 90
74print "%-48s %7s %7s %+7s" % ("function", "old", "new", "delta") 91print "%-48s %7s %7s %+7s" % ("function", "old", "new", "delta")
75for d, n in delta: 92for d, n in delta:
76 if d: print "%-48s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d) 93 if d:
94 old_sz = old.get(n, {}).get("size", "-")
95 new_sz = new.get(n, {}).get("size", "-")
96 print "%-48s %7s %7s %+7d" % (n, old_sz, new_sz, d)
77print "-"*78 97print "-"*78
78total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\ 98total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\
79 % (add, remove, grow, shrink, up, -down, up-down) 99 % (add, remove, grow, shrink, up, -down, up-down)