Skip to content

Instantly share code, notes, and snippets.

@bisco
Last active August 24, 2018 04:25
Show Gist options
  • Save bisco/d50a5c5a78b584019a313f09a5d8fcf2 to your computer and use it in GitHub Desktop.
Save bisco/d50a5c5a78b584019a313f09a5d8fcf2 to your computer and use it in GitHub Desktop.
perf formatter
#!/usr/bin/env python [31/1804]
#fileencoding: utf-8
from __future__ import print_function
import sys
MASK_32BIT = 0xFFFFFFFF
class BranchEntry:
def __init__(self, line):
symaddr, fname_with_offset = line.strip().split(" ")
if "+" in fname_with_offset:
fname, symoffset = fname_with_offset.strip().split("+")
symoffset = int(symoffset, 16)
else:
fname = "[unknown]"
symoffset = 0
symaddr = int(symaddr, 16)
self.fname = fname
self.addr = symaddr - symoffset
self.addr = self.addr & MASK_32BIT
self.offset = symoffset & MASK_32BIT
self.level = 0
self.count = 1
self.child = []
def countup(self):
self.count += 1
def add_child(self, entry):
self.child.append(entry)
def fingerprint(self):
return [self.fname, self.addr, self.offset]
def set_level(self, level):
self.level = level
def get_child(self):
return self.child
def get_count(self):
return self.count
def print_all_leaf(self):
print(self)
for i in sorted(self.child, key=lambda x: x.get_count(), reverse=True):
i.print_all_leaf()
def calc_ratio_all_leaf(self, total_entry_count):
self.ratio = float(self.count * 100) / total_entry_count
for i in self.child:
i.calc_ratio_all_leaf(total_entry_count)
def __str__(self):
return "{:6.2f}%, {}, 0x{:x}, {}, 0x{:x}".format(self.ratio, self.level, self.addr, self.fname, self.offset)
def is_same(a, b):
for i, j in zip(a.fingerprint(), b.fingerprint()):
if i != j:
return False
return True
def do_merge(dst, src):
for d in dst.get_child():
for s in src.get_child():
if is_same(d, s):
d.countup()
do_merge(d, s)
return
for i in src.get_child():
dst.add_child(i)
def merge_branch(root, branch_root):
for r in root:
if is_same(r, branch_root):
r.countup()
do_merge(r, branch_root)
return
root.append(branch_root)
def gen_branch(entries):
branch_root = entries.pop()
current = branch_root
level = 0
for e in entries[::-1]:
level += 1
e.set_level(level)
current.add_child(e)
current = e
return branch_root
def gen_tree(filename):
root = []
entries = []
total_entry_count = 0
with open(filename, "r") as f:
for line in f:
if len(line) == 1:
total_entry_count += 1
branch_root = gen_branch(entries)
merge_branch(root, branch_root)
entries = []
elif "\t" in line:
entries.append(BranchEntry(line))
for r in root:
r.calc_ratio_all_leaf(total_entry_count)
for r in sorted(root, key=lambda x: x.get_count(), reverse=True):
r.print_all_leaf()
def main():
if len(sys.argv) != 2:
print("usage: formatter.py filename")
sys.exit(1)
gen_tree(sys.argv[1])
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment