Skip to content

Commit 7f2eee5

Browse files
committed
Impl differential memap
1 parent 5d5ca62 commit 7f2eee5

File tree

2 files changed

+82
-13
lines changed

2 files changed

+82
-13
lines changed

tools/memap.py

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ class MemapParser(object):
455455
"""
456456

457457
print_sections = ('.text', '.data', '.bss')
458+
delta_sections = ('.text-delta', '.data-delta', '.bss-delta')
458459

459460

460461
# sections to print info (generic for all toolchains)
@@ -466,6 +467,7 @@ def __init__(self):
466467
# list of all modules and their sections
467468
# full list - doesn't change with depth
468469
self.modules = dict()
470+
self.old_modules = None
469471
# short version with specific depth
470472
self.short_modules = dict()
471473

@@ -510,8 +512,18 @@ def reduce_depth(self, depth):
510512
new_name = join(*split_name[:depth])
511513
self.short_modules.setdefault(new_name, defaultdict(int))
512514
for section_idx, value in v.items():
513-
self.short_modules[new_name].setdefault(section_idx, 0)
514515
self.short_modules[new_name][section_idx] += self.modules[module_name][section_idx]
516+
try:
517+
new_size = self.modules[module_name][section_idx]
518+
try:
519+
old_size = self.old_modules[module_name][section_idx]
520+
except KeyError:
521+
old_size = 0
522+
self.short_modules[new_name][section_idx + '-delta'] += (
523+
new_size - old_size
524+
)
525+
except TypeError:
526+
self.short_modules[new_name][section_idx + '-delta'] += 0
515527

516528
export_formats = ["json", "csv-ci", "html", "table"]
517529

@@ -557,7 +569,7 @@ def _move_up_tree(tree, next_module):
557569
if child["name"] == next_module:
558570
return child
559571
else:
560-
new_module = {"name": next_module, "value": 0}
572+
new_module = {"name": next_module, "value": 0, "delta": 0}
561573
tree["children"].append(new_module)
562574
return new_module
563575

@@ -567,9 +579,9 @@ def generate_html(self, file_desc):
567579
Positional arguments:
568580
file_desc - the file to write out the final report to
569581
"""
570-
tree_text = {"name": ".text", "value": 0}
571-
tree_bss = {"name": ".bss", "value": 0}
572-
tree_data = {"name": ".data", "value": 0}
582+
tree_text = {"name": ".text", "value": 0, "delta": 0}
583+
tree_bss = {"name": ".bss", "value": 0, "delta": 0}
584+
tree_data = {"name": ".data", "value": 0, "delta": 0}
573585
for name, dct in self.modules.items():
574586
cur_text = tree_text
575587
cur_bss = tree_bss
@@ -578,14 +590,17 @@ def generate_html(self, file_desc):
578590
while True:
579591
try:
580592
cur_text["value"] += dct['.text']
593+
cur_text["delta"] += dct['.text']
581594
except KeyError:
582595
pass
583596
try:
584597
cur_bss["value"] += dct['.bss']
598+
cur_bss["delta"] += dct['.bss']
585599
except KeyError:
586600
pass
587601
try:
588602
cur_data["value"] += dct['.data']
603+
cur_data["delta"] += dct['.data']
589604
except KeyError:
590605
pass
591606
if not modules:
@@ -594,15 +609,43 @@ def generate_html(self, file_desc):
594609
cur_text = self._move_up_tree(cur_text, next_module)
595610
cur_data = self._move_up_tree(cur_data, next_module)
596611
cur_bss = self._move_up_tree(cur_bss, next_module)
612+
for name, dct in self.old_modules.items():
613+
cur_text = tree_text
614+
cur_bss = tree_bss
615+
cur_data = tree_data
616+
modules = name.split(sep)
617+
while True:
618+
try:
619+
cur_text["delta"] -= dct['.text']
620+
except KeyError:
621+
pass
622+
try:
623+
cur_bss["delta"] -= dct['.bss']
624+
except KeyError:
625+
pass
626+
try:
627+
cur_data["delta"] -= dct['.data']
628+
except KeyError:
629+
pass
630+
if not modules:
631+
break
632+
next_module = modules.pop(0)
633+
if not any(cld['name'] == next_module for cld in cur_text['children']):
634+
break
635+
cur_text = self._move_up_tree(cur_text, next_module)
636+
cur_data = self._move_up_tree(cur_data, next_module)
637+
cur_bss = self._move_up_tree(cur_bss, next_module)
597638

598639
tree_rom = {
599640
"name": "ROM",
600641
"value": tree_text["value"] + tree_data["value"],
642+
"delta": tree_text["delta"] + tree_data["delta"],
601643
"children": [tree_text, tree_data]
602644
}
603645
tree_ram = {
604646
"name": "RAM",
605647
"value": tree_bss["value"] + tree_data["value"],
648+
"delta": tree_bss["delta"] + tree_data["delta"],
606649
"children": [tree_bss, tree_data]
607650
}
608651

@@ -646,7 +689,7 @@ def generate_csv(self, file_desc):
646689
module_section = []
647690
sizes = []
648691
for i in sorted(self.short_modules):
649-
for k in self.print_sections:
692+
for k in self.print_sections + self.delta_sections:
650693
module_section.append((i + k))
651694
sizes += [self.short_modules[i][k]]
652695

@@ -681,7 +724,8 @@ def generate_table(self, file_desc):
681724
row = [i]
682725

683726
for k in self.print_sections:
684-
row.append(self.short_modules[i][k])
727+
row.append("{}({:+})".format(self.short_modules[i][k],
728+
self.short_modules[i][k + "-delta"]))
685729

686730
table.add_row(row)
687731

@@ -724,7 +768,8 @@ def compute_report(self):
724768
self.mem_report.append({
725769
"module": name,
726770
"size":{
727-
k: sizes.get(k, 0) for k in self.print_sections
771+
k: sizes.get(k, 0) for k in (self.print_sections +
772+
self.delta_sections)
728773
}
729774
})
730775

@@ -741,16 +786,21 @@ def parse(self, mapfile, toolchain):
741786
"""
742787
self.tc_name = toolchain.title()
743788
if toolchain in ("ARM", "ARM_STD", "ARM_MICRO", "ARMC6"):
744-
parser = _ArmccParser()
789+
parser = _ArmccParser
745790
elif toolchain == "GCC_ARM" or toolchain == "GCC_CR":
746-
parser = _GccParser()
791+
parser = _GccParser
747792
elif toolchain == "IAR":
748-
parser = _IarParser()
793+
parser = _IarParser
749794
else:
750795
return False
751796
try:
752797
with open(mapfile, 'r') as file_input:
753-
self.modules = parser.parse_mapfile(file_input)
798+
self.modules = parser().parse_mapfile(file_input)
799+
try:
800+
with open("%s.old" % mapfile, 'r') as old_input:
801+
self.old_modules = parser().parse_mapfile(old_input)
802+
except IOError:
803+
self.old_modules = None
754804
return True
755805

756806
except IOError as error:

tools/memap_flamegraph.html

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,35 @@ <h3 class="text-muted">{{name}} Memory Details</h3>
8080
.direction("s")
8181
.offset([8, 0])
8282
.attr('class', 'd3-flame-graph-tip')
83-
.html(function(d) { return "module: " + d.data.name + ", bytes: " + d.data.value; });
83+
.html(function(d) { return "module: " + d.data.name + ", bytes: " + d.data.value + ", delta: " + d.data.delta; });
84+
var colorizer = function (d) {
85+
if (d.data.delta > 0) {
86+
ratio = (d.data.value - d.data.delta) / d.data.value;
87+
green = ("0" + (Number(ratio * 0xFF | 0).toString(16))).slice(-2).toUpperCase();
88+
blue = ("0" + (Number(ratio * 0xEE | 0).toString(16))).slice(-2).toUpperCase();
89+
console.log(d.data.name, green, blue);
90+
return "#EE" + green + blue
91+
} else if (d.data.delta < 0) {
92+
ratio = (d.data.value + d.data.delta) / d.data.value;
93+
green = ("0" + (Number(ratio * 0xFF | 0).toString(16))).slice(-2).toUpperCase();
94+
red = ("0" + (Number(ratio * 0xFF | 0).toString(16))).slice(-2).toUpperCase();
95+
console.log(d.data.name, red, green);
96+
return "#" + red + green + "EE";
97+
} else {
98+
return "#FFFFEE";
99+
}
100+
}
84101
var flameGraph_rom = d3.flameGraph()
85102
.transitionDuration(250)
86103
.transitionEase(d3.easeCubic)
87104
.sort(true)
105+
.color(colorizer)
88106
.tooltip(tip);
89107
var flameGraph_ram = d3.flameGraph()
90108
.transitionDuration(250)
91109
.transitionEase(d3.easeCubic)
92110
.sort(true)
111+
.color(colorizer)
93112
.tooltip(tip);
94113
var rom_elem = d3.select("#chart-rom");
95114
flameGraph_rom.width(rom_elem.node().getBoundingClientRect().width);

0 commit comments

Comments
 (0)