mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-26 09:28:13 +00:00
feat(core): tools/alloc.py: generate html
This commit is contained in:
parent
c89a8b7bd5
commit
62a80e1332
@ -1,8 +1,11 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
import click
|
import click
|
||||||
|
|
||||||
|
HERE = Path(__file__).parent.resolve()
|
||||||
|
|
||||||
|
|
||||||
def parse_alloc_data(alloc_data):
|
def parse_alloc_data(alloc_data):
|
||||||
parsed_data = {}
|
parsed_data = {}
|
||||||
@ -30,17 +33,23 @@ def cli(ctx, alloc_data, type):
|
|||||||
ctx.obj = SimpleNamespace(data=parse_alloc_data(alloc_data), type=type)
|
ctx.obj = SimpleNamespace(data=parse_alloc_data(alloc_data), type=type)
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_filename(filename):
|
||||||
|
if filename.startswith("src/"):
|
||||||
|
return filename[4:]
|
||||||
|
return filename
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@click.pass_obj
|
@click.pass_obj
|
||||||
@click.argument("filename")
|
@click.argument("filename")
|
||||||
def annotate(obj, filename):
|
def annotate(obj, filename):
|
||||||
|
filename = _normalize_filename(filename)
|
||||||
|
|
||||||
if obj.type == "total":
|
if obj.type == "total":
|
||||||
alloc_str = lambda line: str(line["total_allocs"])
|
alloc_str = lambda line: str(line["total_allocs"])
|
||||||
else:
|
else:
|
||||||
alloc_str = lambda line: "{:.2f}".format(line["avg_allocs"])
|
alloc_str = lambda line: "{:.2f}".format(line["avg_allocs"])
|
||||||
|
|
||||||
if filename.startswith("src/"):
|
|
||||||
filename = filename[4:]
|
|
||||||
filedata = obj.data[filename]
|
filedata = obj.data[filename]
|
||||||
|
|
||||||
linedata = {lineno: alloc_str(line) for lineno, line in filedata.items()}
|
linedata = {lineno: alloc_str(line) for lineno, line in filedata.items()}
|
||||||
@ -53,30 +62,110 @@ def annotate(obj, filename):
|
|||||||
print(f"{linecount:>{maxlen}} {line}", end="")
|
print(f"{linecount:>{maxlen}} {line}", end="")
|
||||||
|
|
||||||
|
|
||||||
|
def _list(obj, sort_by="avg_allocs", reverse=False):
|
||||||
|
return sorted(
|
||||||
|
(
|
||||||
|
(
|
||||||
|
filename,
|
||||||
|
sum(line["avg_allocs"] for line in lines.values()),
|
||||||
|
sum(line["total_allocs"] for line in lines.values()),
|
||||||
|
)
|
||||||
|
for filename, lines in obj.data.items()
|
||||||
|
),
|
||||||
|
key=lambda x: x[1 if sort_by == "avg_allocs" else 2],
|
||||||
|
reverse=reverse,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@click.pass_obj
|
@click.pass_obj
|
||||||
@click.option("-r", "--reverse", is_flag=True)
|
@click.option("-r", "--reverse", is_flag=True)
|
||||||
def list(obj, reverse):
|
def list(obj, reverse):
|
||||||
if obj.type == "total":
|
if obj.type == "total":
|
||||||
field = "total_allocs"
|
field = "total_allocs"
|
||||||
field_fmt = "{}"
|
format_num = lambda l: "{}".format(l[2])
|
||||||
else:
|
else:
|
||||||
field = "avg_allocs"
|
field = "avg_allocs"
|
||||||
field_fmt = "{:.2f}"
|
format_num = lambda l: "{:.2f}".format(l[1])
|
||||||
|
|
||||||
file_sums = {
|
file_sums = _list(obj, field, reverse)
|
||||||
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())
|
maxlen = max(len(format_num(l)) for l in file_sums)
|
||||||
|
for l in file_sums:
|
||||||
for filename, file_sum in sorted(
|
num_str = format_num(l)
|
||||||
file_sums.items(), key=lambda x: x[1], reverse=reverse
|
filename = l[0]
|
||||||
):
|
|
||||||
num_str = field_fmt.format(file_sum)
|
|
||||||
print(f"{num_str:>{maxlen}} {filename}")
|
print(f"{num_str:>{maxlen}} {filename}")
|
||||||
|
|
||||||
|
|
||||||
|
class HtmlTable:
|
||||||
|
def __init__(self, f):
|
||||||
|
self.f = f
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.f.write("<table>")
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, type, value, traceback):
|
||||||
|
self.f.write("</table>")
|
||||||
|
|
||||||
|
def tr(self, *tds):
|
||||||
|
self.f.write("<tr>")
|
||||||
|
for td in tds:
|
||||||
|
if isinstance(td, tuple):
|
||||||
|
self.f.write("<td {}><tt>{}</tt></td>".format(td[0], td[1]))
|
||||||
|
else:
|
||||||
|
self.f.write(f"<td><tt>{td}</tt></td>")
|
||||||
|
self.f.write("</tr>")
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command()
|
||||||
|
@click.pass_obj
|
||||||
|
@click.argument("htmldir")
|
||||||
|
def html(obj, htmldir):
|
||||||
|
file_sums = _list(obj, "total_allocs", reverse=True)
|
||||||
|
style_grey = "style='color: grey'"
|
||||||
|
style_right = "style='text-align: right'"
|
||||||
|
|
||||||
|
with open(f"{htmldir}/index.html", "w") as f:
|
||||||
|
f.write("<html>")
|
||||||
|
with HtmlTable(f) as table:
|
||||||
|
table.tr((style_right, "avg"), (style_right, "total"), "")
|
||||||
|
for filename, avg_sum, total_sum in file_sums:
|
||||||
|
table.tr(
|
||||||
|
(style_right, f"{avg_sum:.2f}"),
|
||||||
|
(style_right, total_sum),
|
||||||
|
f"<a href='{filename}.html'>{filename}</a>",
|
||||||
|
)
|
||||||
|
f.write("</html>")
|
||||||
|
|
||||||
|
for filename in file_sums:
|
||||||
|
filename = _normalize_filename(filename[0])
|
||||||
|
htmlfile = Path(htmldir) / filename
|
||||||
|
htmlfile.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
with open(str(htmlfile) + ".html", "w") as f:
|
||||||
|
filedata = obj.data[filename]
|
||||||
|
f.write(f"<html><title>{filename}</title>")
|
||||||
|
with HtmlTable(f) as table:
|
||||||
|
table.tr(
|
||||||
|
(style_grey, "#"), (style_right, "avg"), (style_right, "total"), ""
|
||||||
|
)
|
||||||
|
|
||||||
|
lineno = 0
|
||||||
|
for line in open(HERE.parent / "src" / filename):
|
||||||
|
line = line.rstrip("\n").replace(" ", " ")
|
||||||
|
lineno += 1
|
||||||
|
total = filedata.get(lineno, {}).get("total_allocs", 0)
|
||||||
|
avg = filedata.get(lineno, {}).get("avg_allocs", 0)
|
||||||
|
|
||||||
|
table.tr(
|
||||||
|
(style_grey, lineno),
|
||||||
|
(style_right, f"{avg:.2f}"),
|
||||||
|
(style_right, total),
|
||||||
|
line,
|
||||||
|
)
|
||||||
|
f.write("</html>")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cli()
|
cli()
|
||||||
|
Loading…
Reference in New Issue
Block a user