mirror of https://github.com/ARMmbed/mbed-os.git
Impl differential memap
parent
5d5ca62a5e
commit
7f2eee564c
|
@ -455,6 +455,7 @@ class MemapParser(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
print_sections = ('.text', '.data', '.bss')
|
print_sections = ('.text', '.data', '.bss')
|
||||||
|
delta_sections = ('.text-delta', '.data-delta', '.bss-delta')
|
||||||
|
|
||||||
|
|
||||||
# sections to print info (generic for all toolchains)
|
# sections to print info (generic for all toolchains)
|
||||||
|
@ -466,6 +467,7 @@ class MemapParser(object):
|
||||||
# list of all modules and their sections
|
# list of all modules and their sections
|
||||||
# full list - doesn't change with depth
|
# full list - doesn't change with depth
|
||||||
self.modules = dict()
|
self.modules = dict()
|
||||||
|
self.old_modules = None
|
||||||
# short version with specific depth
|
# short version with specific depth
|
||||||
self.short_modules = dict()
|
self.short_modules = dict()
|
||||||
|
|
||||||
|
@ -510,8 +512,18 @@ class MemapParser(object):
|
||||||
new_name = join(*split_name[:depth])
|
new_name = join(*split_name[:depth])
|
||||||
self.short_modules.setdefault(new_name, defaultdict(int))
|
self.short_modules.setdefault(new_name, defaultdict(int))
|
||||||
for section_idx, value in v.items():
|
for section_idx, value in v.items():
|
||||||
self.short_modules[new_name].setdefault(section_idx, 0)
|
|
||||||
self.short_modules[new_name][section_idx] += self.modules[module_name][section_idx]
|
self.short_modules[new_name][section_idx] += self.modules[module_name][section_idx]
|
||||||
|
try:
|
||||||
|
new_size = self.modules[module_name][section_idx]
|
||||||
|
try:
|
||||||
|
old_size = self.old_modules[module_name][section_idx]
|
||||||
|
except KeyError:
|
||||||
|
old_size = 0
|
||||||
|
self.short_modules[new_name][section_idx + '-delta'] += (
|
||||||
|
new_size - old_size
|
||||||
|
)
|
||||||
|
except TypeError:
|
||||||
|
self.short_modules[new_name][section_idx + '-delta'] += 0
|
||||||
|
|
||||||
export_formats = ["json", "csv-ci", "html", "table"]
|
export_formats = ["json", "csv-ci", "html", "table"]
|
||||||
|
|
||||||
|
@ -557,7 +569,7 @@ class MemapParser(object):
|
||||||
if child["name"] == next_module:
|
if child["name"] == next_module:
|
||||||
return child
|
return child
|
||||||
else:
|
else:
|
||||||
new_module = {"name": next_module, "value": 0}
|
new_module = {"name": next_module, "value": 0, "delta": 0}
|
||||||
tree["children"].append(new_module)
|
tree["children"].append(new_module)
|
||||||
return new_module
|
return new_module
|
||||||
|
|
||||||
|
@ -567,9 +579,9 @@ class MemapParser(object):
|
||||||
Positional arguments:
|
Positional arguments:
|
||||||
file_desc - the file to write out the final report to
|
file_desc - the file to write out the final report to
|
||||||
"""
|
"""
|
||||||
tree_text = {"name": ".text", "value": 0}
|
tree_text = {"name": ".text", "value": 0, "delta": 0}
|
||||||
tree_bss = {"name": ".bss", "value": 0}
|
tree_bss = {"name": ".bss", "value": 0, "delta": 0}
|
||||||
tree_data = {"name": ".data", "value": 0}
|
tree_data = {"name": ".data", "value": 0, "delta": 0}
|
||||||
for name, dct in self.modules.items():
|
for name, dct in self.modules.items():
|
||||||
cur_text = tree_text
|
cur_text = tree_text
|
||||||
cur_bss = tree_bss
|
cur_bss = tree_bss
|
||||||
|
@ -578,14 +590,17 @@ class MemapParser(object):
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
cur_text["value"] += dct['.text']
|
cur_text["value"] += dct['.text']
|
||||||
|
cur_text["delta"] += dct['.text']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
cur_bss["value"] += dct['.bss']
|
cur_bss["value"] += dct['.bss']
|
||||||
|
cur_bss["delta"] += dct['.bss']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
cur_data["value"] += dct['.data']
|
cur_data["value"] += dct['.data']
|
||||||
|
cur_data["delta"] += dct['.data']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
if not modules:
|
if not modules:
|
||||||
|
@ -594,15 +609,43 @@ class MemapParser(object):
|
||||||
cur_text = self._move_up_tree(cur_text, next_module)
|
cur_text = self._move_up_tree(cur_text, next_module)
|
||||||
cur_data = self._move_up_tree(cur_data, next_module)
|
cur_data = self._move_up_tree(cur_data, next_module)
|
||||||
cur_bss = self._move_up_tree(cur_bss, next_module)
|
cur_bss = self._move_up_tree(cur_bss, next_module)
|
||||||
|
for name, dct in self.old_modules.items():
|
||||||
|
cur_text = tree_text
|
||||||
|
cur_bss = tree_bss
|
||||||
|
cur_data = tree_data
|
||||||
|
modules = name.split(sep)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
cur_text["delta"] -= dct['.text']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
cur_bss["delta"] -= dct['.bss']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
cur_data["delta"] -= dct['.data']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
if not modules:
|
||||||
|
break
|
||||||
|
next_module = modules.pop(0)
|
||||||
|
if not any(cld['name'] == next_module for cld in cur_text['children']):
|
||||||
|
break
|
||||||
|
cur_text = self._move_up_tree(cur_text, next_module)
|
||||||
|
cur_data = self._move_up_tree(cur_data, next_module)
|
||||||
|
cur_bss = self._move_up_tree(cur_bss, next_module)
|
||||||
|
|
||||||
tree_rom = {
|
tree_rom = {
|
||||||
"name": "ROM",
|
"name": "ROM",
|
||||||
"value": tree_text["value"] + tree_data["value"],
|
"value": tree_text["value"] + tree_data["value"],
|
||||||
|
"delta": tree_text["delta"] + tree_data["delta"],
|
||||||
"children": [tree_text, tree_data]
|
"children": [tree_text, tree_data]
|
||||||
}
|
}
|
||||||
tree_ram = {
|
tree_ram = {
|
||||||
"name": "RAM",
|
"name": "RAM",
|
||||||
"value": tree_bss["value"] + tree_data["value"],
|
"value": tree_bss["value"] + tree_data["value"],
|
||||||
|
"delta": tree_bss["delta"] + tree_data["delta"],
|
||||||
"children": [tree_bss, tree_data]
|
"children": [tree_bss, tree_data]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,7 +689,7 @@ class MemapParser(object):
|
||||||
module_section = []
|
module_section = []
|
||||||
sizes = []
|
sizes = []
|
||||||
for i in sorted(self.short_modules):
|
for i in sorted(self.short_modules):
|
||||||
for k in self.print_sections:
|
for k in self.print_sections + self.delta_sections:
|
||||||
module_section.append((i + k))
|
module_section.append((i + k))
|
||||||
sizes += [self.short_modules[i][k]]
|
sizes += [self.short_modules[i][k]]
|
||||||
|
|
||||||
|
@ -681,7 +724,8 @@ class MemapParser(object):
|
||||||
row = [i]
|
row = [i]
|
||||||
|
|
||||||
for k in self.print_sections:
|
for k in self.print_sections:
|
||||||
row.append(self.short_modules[i][k])
|
row.append("{}({:+})".format(self.short_modules[i][k],
|
||||||
|
self.short_modules[i][k + "-delta"]))
|
||||||
|
|
||||||
table.add_row(row)
|
table.add_row(row)
|
||||||
|
|
||||||
|
@ -724,7 +768,8 @@ class MemapParser(object):
|
||||||
self.mem_report.append({
|
self.mem_report.append({
|
||||||
"module": name,
|
"module": name,
|
||||||
"size":{
|
"size":{
|
||||||
k: sizes.get(k, 0) for k in self.print_sections
|
k: sizes.get(k, 0) for k in (self.print_sections +
|
||||||
|
self.delta_sections)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -741,16 +786,21 @@ class MemapParser(object):
|
||||||
"""
|
"""
|
||||||
self.tc_name = toolchain.title()
|
self.tc_name = toolchain.title()
|
||||||
if toolchain in ("ARM", "ARM_STD", "ARM_MICRO", "ARMC6"):
|
if toolchain in ("ARM", "ARM_STD", "ARM_MICRO", "ARMC6"):
|
||||||
parser = _ArmccParser()
|
parser = _ArmccParser
|
||||||
elif toolchain == "GCC_ARM" or toolchain == "GCC_CR":
|
elif toolchain == "GCC_ARM" or toolchain == "GCC_CR":
|
||||||
parser = _GccParser()
|
parser = _GccParser
|
||||||
elif toolchain == "IAR":
|
elif toolchain == "IAR":
|
||||||
parser = _IarParser()
|
parser = _IarParser
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
with open(mapfile, 'r') as file_input:
|
with open(mapfile, 'r') as file_input:
|
||||||
self.modules = parser.parse_mapfile(file_input)
|
self.modules = parser().parse_mapfile(file_input)
|
||||||
|
try:
|
||||||
|
with open("%s.old" % mapfile, 'r') as old_input:
|
||||||
|
self.old_modules = parser().parse_mapfile(old_input)
|
||||||
|
except IOError:
|
||||||
|
self.old_modules = None
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except IOError as error:
|
except IOError as error:
|
||||||
|
|
|
@ -80,16 +80,35 @@
|
||||||
.direction("s")
|
.direction("s")
|
||||||
.offset([8, 0])
|
.offset([8, 0])
|
||||||
.attr('class', 'd3-flame-graph-tip')
|
.attr('class', 'd3-flame-graph-tip')
|
||||||
.html(function(d) { return "module: " + d.data.name + ", bytes: " + d.data.value; });
|
.html(function(d) { return "module: " + d.data.name + ", bytes: " + d.data.value + ", delta: " + d.data.delta; });
|
||||||
|
var colorizer = function (d) {
|
||||||
|
if (d.data.delta > 0) {
|
||||||
|
ratio = (d.data.value - d.data.delta) / d.data.value;
|
||||||
|
green = ("0" + (Number(ratio * 0xFF | 0).toString(16))).slice(-2).toUpperCase();
|
||||||
|
blue = ("0" + (Number(ratio * 0xEE | 0).toString(16))).slice(-2).toUpperCase();
|
||||||
|
console.log(d.data.name, green, blue);
|
||||||
|
return "#EE" + green + blue
|
||||||
|
} else if (d.data.delta < 0) {
|
||||||
|
ratio = (d.data.value + d.data.delta) / d.data.value;
|
||||||
|
green = ("0" + (Number(ratio * 0xFF | 0).toString(16))).slice(-2).toUpperCase();
|
||||||
|
red = ("0" + (Number(ratio * 0xFF | 0).toString(16))).slice(-2).toUpperCase();
|
||||||
|
console.log(d.data.name, red, green);
|
||||||
|
return "#" + red + green + "EE";
|
||||||
|
} else {
|
||||||
|
return "#FFFFEE";
|
||||||
|
}
|
||||||
|
}
|
||||||
var flameGraph_rom = d3.flameGraph()
|
var flameGraph_rom = d3.flameGraph()
|
||||||
.transitionDuration(250)
|
.transitionDuration(250)
|
||||||
.transitionEase(d3.easeCubic)
|
.transitionEase(d3.easeCubic)
|
||||||
.sort(true)
|
.sort(true)
|
||||||
|
.color(colorizer)
|
||||||
.tooltip(tip);
|
.tooltip(tip);
|
||||||
var flameGraph_ram = d3.flameGraph()
|
var flameGraph_ram = d3.flameGraph()
|
||||||
.transitionDuration(250)
|
.transitionDuration(250)
|
||||||
.transitionEase(d3.easeCubic)
|
.transitionEase(d3.easeCubic)
|
||||||
.sort(true)
|
.sort(true)
|
||||||
|
.color(colorizer)
|
||||||
.tooltip(tip);
|
.tooltip(tip);
|
||||||
var rom_elem = d3.select("#chart-rom");
|
var rom_elem = d3.select("#chart-rom");
|
||||||
flameGraph_rom.width(rom_elem.node().getBoundingClientRect().width);
|
flameGraph_rom.width(rom_elem.node().getBoundingClientRect().width);
|
||||||
|
|
Loading…
Reference in New Issue