1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-18 13:38:12 +00:00
trezor-firmware/core/tools/alloc.py
matejcik 93efe3ab63 feat(core): add alloc data analysis tool
Modified by mmilata, was:
add alloc data from test suite run, and an analysis tool
2020-11-02 14:14:00 +01:00

83 lines
2.2 KiB
Python
Executable File

#!/usr/bin/env python3
from types import SimpleNamespace
import click
def parse_alloc_data(alloc_data):
parsed_data = {}
for line in alloc_data:
ident, allocs, calls = line.strip().split(" ")
allocs = int(allocs)
calls = int(calls)
filename, lineno = ident.split(":")
lineno = int(lineno)
filedata = parsed_data.setdefault(filename, {})
filedata[lineno] = {
"total_allocs": allocs,
"total_calls": calls,
"avg_allocs": allocs / calls,
}
return parsed_data
@click.group()
@click.pass_context
@click.option("-a", "--alloc-data", type=click.File(), default="src/alloc_data.txt")
@click.option("-t", "--type", type=click.Choice(("total", "avg")), default="avg")
def cli(ctx, alloc_data, type):
ctx.obj = SimpleNamespace(data=parse_alloc_data(alloc_data), type=type)
@cli.command()
@click.pass_obj
@click.argument("filename")
def annotate(obj, filename):
if obj.type == "total":
alloc_str = lambda line: str(line["total_allocs"])
else:
alloc_str = lambda line: "{:.2f}".format(line["avg_allocs"])
if filename.startswith("src/"):
filename = filename[4:]
filedata = obj.data[filename]
linedata = {lineno: alloc_str(line) for lineno, line in filedata.items()}
maxlen = max(len(l) for l in linedata.values())
lineno = 0
for line in open("src/" + filename):
lineno += 1
linecount = linedata.get(lineno, "")
print(f"{linecount:>{maxlen}} {line}", end="")
@cli.command()
@click.pass_obj
@click.option("-r", "--reverse", is_flag=True)
def list(obj, reverse):
if obj.type == "total":
field = "total_allocs"
field_fmt = "{}"
else:
field = "avg_allocs"
field_fmt = "{:.2f}"
file_sums = {
filename: sum(line[field] for line in lines.values())
for filename, lines in obj.data.items()
}
maxlen = max(len(field_fmt.format(l)) for l in file_sums.values())
for filename, file_sum in sorted(
file_sums.items(), key=lambda x: x[1], reverse=reverse
):
num_str = field_fmt.format(file_sum)
print(f"{num_str:>{maxlen}} {filename}")
if __name__ == "__main__":
cli()