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) |