Annotation of embedaddon/dnsmasq/bld/bloat-o-meter, revision 1.1
1.1 ! misho 1: #!/usr/bin/env python
! 2: #
! 3: # Copyright 2004 Matt Mackall <mpm@selenic.com>
! 4: #
! 5: # Inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen
! 6: #
! 7: # This software may be used and distributed according to the terms
! 8: # of the GNU General Public License, incorporated herein by reference.
! 9:
! 10: import sys, os#, re
! 11:
! 12: def usage():
! 13: sys.stderr.write("usage: %s [-t] file1 file2\n" % sys.argv[0])
! 14: sys.exit(-1)
! 15:
! 16: f1, f2 = (None, None)
! 17: flag_timing, dashes = (False, False)
! 18:
! 19: for f in sys.argv[1:]:
! 20: if f.startswith("-"):
! 21: if f == "--": # sym_args
! 22: dashes = True
! 23: break
! 24: if f == "-t": # timings
! 25: flag_timing = True
! 26: else:
! 27: if not os.path.exists(f):
! 28: sys.stderr.write("Error: file '%s' does not exist\n" % f)
! 29: usage()
! 30: if f1 is None:
! 31: f1 = f
! 32: elif f2 is None:
! 33: f2 = f
! 34: if flag_timing:
! 35: import time
! 36: if f1 is None or f2 is None:
! 37: usage()
! 38:
! 39: sym_args = " ".join(sys.argv[3 + flag_timing + dashes:])
! 40: def getsizes(file):
! 41: sym, alias, lut = {}, {}, {}
! 42: for l in os.popen("readelf -W -s %s %s" % (sym_args, file)).readlines():
! 43: l = l.strip()
! 44: if not (len(l) and l[0].isdigit() and len(l.split()) == 8):
! 45: continue
! 46: num, value, size, typ, bind, vis, ndx, name = l.split()
! 47: if ndx == "UND": continue # skip undefined
! 48: if typ in ["SECTION", "FILES"]: continue # skip sections and files
! 49: if "." in name: name = "static." + name.split(".")[0]
! 50: value = int(value, 16)
! 51: size = int(size, 16) if size.startswith('0x') else int(size)
! 52: if vis != "DEFAULT" and bind != "GLOBAL": # see if it is an alias
! 53: alias[(value, size)] = {"name" : name}
! 54: else:
! 55: sym[name] = {"addr" : value, "size": size}
! 56: lut[(value, size)] = 0
! 57: for addr, sz in iter(alias.keys()):
! 58: # If the non-GLOBAL sym has an implementation elsewhere then
! 59: # it's an alias, disregard it.
! 60: if not (addr, sz) in lut:
! 61: # If this non-GLOBAL sym does not have an implementation at
! 62: # another address, then treat it as a normal symbol.
! 63: sym[alias[(addr, sz)]["name"]] = {"addr" : addr, "size": sz}
! 64: for l in os.popen("readelf -W -S " + file).readlines():
! 65: x = l.split()
! 66: if len(x)<6: continue
! 67: # Should take these into account too!
! 68: #if x[1] not in [".text", ".rodata", ".symtab", ".strtab"]: continue
! 69: if x[1] not in [".rodata"]: continue
! 70: sym[x[1]] = {"addr" : int(x[3], 16), "size" : int(x[5], 16)}
! 71: return sym
! 72:
! 73: if flag_timing:
! 74: start_t1 = int(time.time() * 1e9)
! 75: old = getsizes(f1)
! 76: if flag_timing:
! 77: end_t1 = int(time.time() * 1e9)
! 78: start_t2 = int(time.time() * 1e9)
! 79: new = getsizes(f2)
! 80: if flag_timing:
! 81: end_t2 = int(time.time() * 1e9)
! 82: start_t3 = int(time.time() * 1e9)
! 83: grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
! 84: delta, common = [], {}
! 85:
! 86: for name in iter(old.keys()):
! 87: if name in new:
! 88: common[name] = 1
! 89:
! 90: for name in old:
! 91: if name not in common:
! 92: remove += 1
! 93: sz = old[name]["size"]
! 94: down += sz
! 95: delta.append((-sz, name))
! 96:
! 97: for name in new:
! 98: if name not in common:
! 99: add += 1
! 100: sz = new[name]["size"]
! 101: up += sz
! 102: delta.append((sz, name))
! 103:
! 104: for name in common:
! 105: d = new[name].get("size", 0) - old[name].get("size", 0)
! 106: if d>0: grow, up = grow+1, up+d
! 107: elif d<0: shrink, down = shrink+1, down-d
! 108: else:
! 109: continue
! 110: delta.append((d, name))
! 111:
! 112: delta.sort()
! 113: delta.reverse()
! 114: if flag_timing:
! 115: end_t3 = int(time.time() * 1e9)
! 116:
! 117: print("%-48s %7s %7s %+7s" % ("function", "old", "new", "delta"))
! 118: for d, n in delta:
! 119: if d:
! 120: old_sz = old.get(n, {}).get("size", "-")
! 121: new_sz = new.get(n, {}).get("size", "-")
! 122: print("%-48s %7s %7s %+7d" % (n, old_sz, new_sz, d))
! 123: print("-"*78)
! 124: total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\
! 125: % (add, remove, grow, shrink, up, -down, up-down)
! 126: print(total % (" "*(80-len(total))))
! 127: if flag_timing:
! 128: print("\n%d/%d; %d Parse origin/new; processing nsecs" %
! 129: (end_t1-start_t1, end_t2-start_t2, end_t3-start_t3))
! 130: print("total nsecs: %d" % (end_t3-start_t1))
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>