| Index: tools/binary_size/libsupersize/models.py
|
| diff --git a/tools/binary_size/libsupersize/models.py b/tools/binary_size/libsupersize/models.py
|
| index 7e2ceb1c123752c70afe25604f95a280eec36b45..5f611d13d8239d7c9a3964b36c8212f1af0d4423 100644
|
| --- a/tools/binary_size/libsupersize/models.py
|
| +++ b/tools/binary_size/libsupersize/models.py
|
| @@ -10,6 +10,8 @@ Description of common properties:
|
| May be 0 (e.g. for .bss or for SymbolGroups).
|
| * size: The number of bytes this symbol takes up, including padding that comes
|
| before |address|.
|
| + * num_aliases: The number of symbols with the same address (including self).
|
| + * pss: size / num_aliases.
|
| * padding: The number of bytes of padding before |address| due to this symbol.
|
| * name: Symbol names with parameter list removed.
|
| Never None, but will be '' for anonymous symbols.
|
| @@ -24,6 +26,7 @@ Description of common properties:
|
|
|
| import collections
|
| import copy
|
| +import logging
|
| import os
|
| import re
|
|
|
| @@ -159,6 +162,7 @@ class Symbol(BaseSymbol):
|
| 'is_anonymous',
|
| 'object_path',
|
| 'name',
|
| + 'num_aliases',
|
| 'padding',
|
| 'section_name',
|
| 'source_path',
|
| @@ -167,7 +171,7 @@ class Symbol(BaseSymbol):
|
|
|
| def __init__(self, section_name, size_without_padding, address=None,
|
| name=None, source_path=None, object_path=None,
|
| - full_name=None, is_anonymous=False):
|
| + full_name=None, is_anonymous=False, num_aliases=1):
|
| self.section_name = section_name
|
| self.address = address or 0
|
| self.name = name or ''
|
| @@ -175,9 +179,8 @@ class Symbol(BaseSymbol):
|
| self.source_path = source_path or ''
|
| self.object_path = object_path or ''
|
| self.size = size_without_padding
|
| - # Change this to be a bitfield of flags if ever there is a need to add
|
| - # another similar thing.
|
| self.is_anonymous = is_anonymous
|
| + self.num_aliases = num_aliases
|
| self.padding = 0
|
|
|
| def __repr__(self):
|
| @@ -186,6 +189,14 @@ class Symbol(BaseSymbol):
|
| self.padding, self.name, self.source_path or self.object_path,
|
| int(self.is_anonymous)))
|
|
|
| + @property
|
| + def pss(self):
|
| + return float(self.size) / self.num_aliases
|
| +
|
| + @property
|
| + def pss_without_padding(self):
|
| + return float(self.size_without_padding) / self.num_aliases
|
| +
|
|
|
| class SymbolGroup(BaseSymbol):
|
| """Represents a group of symbols using the same interface as Symbol.
|
| @@ -205,6 +216,7 @@ class SymbolGroup(BaseSymbol):
|
| __slots__ = (
|
| '_padding',
|
| '_size',
|
| + '_pss',
|
| '_symbols',
|
| '_filtered_symbols',
|
| 'full_name',
|
| @@ -217,6 +229,7 @@ class SymbolGroup(BaseSymbol):
|
| full_name=None, section_name=None, is_sorted=False):
|
| self._padding = None
|
| self._size = None
|
| + self._pss = None
|
| self._symbols = symbols
|
| self._filtered_symbols = filtered_symbols or []
|
| self.name = name or ''
|
| @@ -277,27 +290,50 @@ class SymbolGroup(BaseSymbol):
|
| @property
|
| def object_path(self):
|
| first = self._symbols[0].object_path
|
| - return first if all(s.object_path == first for s in self._symbols) else None
|
| + return first if all(s.object_path == first for s in self._symbols) else ''
|
|
|
| @property
|
| def source_path(self):
|
| first = self._symbols[0].source_path
|
| - return first if all(s.source_path == first for s in self._symbols) else None
|
| + return first if all(s.source_path == first for s in self._symbols) else ''
|
| +
|
| + def IterUniqueSymbols(self):
|
| + seen_addresses = set()
|
| + for s in self:
|
| + if s.num_aliases == 1:
|
| + yield s
|
| + elif s.address not in seen_addresses:
|
| + seen_addresses.add(s.address)
|
| + yield s
|
|
|
| @property
|
| def size(self):
|
| if self._size is None:
|
| if self.IsBss():
|
| self._size = sum(s.size for s in self)
|
| - self._size = sum(s.size for s in self if not s.IsBss())
|
| + else:
|
| + self._size = sum(s.size for s in self.IterUniqueSymbols())
|
| return self._size
|
|
|
| @property
|
| + def pss(self):
|
| + if self._pss is None:
|
| + if self.IsBss():
|
| + self._pss = self.size
|
| + else:
|
| + self._pss = sum(s.pss for s in self)
|
| + return self._pss
|
| +
|
| + @property
|
| def padding(self):
|
| if self._padding is None:
|
| - self._padding = sum(s.padding for s in self)
|
| + self._padding = sum(s.padding for s in self.IterUniqueSymbols())
|
| return self._padding
|
|
|
| + @property
|
| + def num_aliases(self):
|
| + return 1
|
| +
|
| def IsGroup(self):
|
| return True
|
|
|
| @@ -331,8 +367,14 @@ class SymbolGroup(BaseSymbol):
|
|
|
| def Filter(self, func):
|
| filtered_and_kept = ([], [])
|
| - for symbol in self:
|
| - filtered_and_kept[int(bool(func(symbol)))].append(symbol)
|
| + symbol = None
|
| + try:
|
| + for symbol in self:
|
| + filtered_and_kept[int(bool(func(symbol)))].append(symbol)
|
| + except:
|
| + logging.warning('Filter failed on symbol %r', symbol)
|
| + raise
|
| +
|
| return self._CreateTransformed(filtered_and_kept[1],
|
| filtered_symbols=filtered_and_kept[0],
|
| section_name=self.section_name)
|
|
|