Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(307)

Unified Diff: tools/binary_size/models.py

Issue 2795593005: //tools/binary_size: Various enhancements to console.py (Closed)
Patch Set: Review fixes Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/binary_size/match_util_test.py ('k') | tools/binary_size/testdata/ActualDiff.golden » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/binary_size/models.py
diff --git a/tools/binary_size/models.py b/tools/binary_size/models.py
index f73b0fe56f42d1431ac4da1ddf6208565284345a..ecc3527e88c6a633cea991ee75cb68bbce21c728 100644
--- a/tools/binary_size/models.py
+++ b/tools/binary_size/models.py
@@ -8,6 +8,8 @@ import copy
import os
import re
+import match_util
+
SECTION_TO_SECTION_NAME = {
'b': '.bss',
@@ -89,7 +91,6 @@ class Symbol(BaseSymbol):
'is_anonymous',
'object_path',
'name',
- 'flags',
'padding',
'section_name',
'source_path',
@@ -123,44 +124,76 @@ class SymbolGroup(BaseSymbol):
SymbolGroups are immutable. All filtering / sorting will return new
SymbolGroups objects.
+
+ Overrides many __functions__. E.g. the following are all valid:
+ * len(group)
+ * iter(group)
+ * group[0]
+ * group['0x1234'] # By symbol address
+ * without_group2 = group1 - group2
+ * unioned = group1 + group2
"""
__slots__ = (
- 'symbols',
- 'filtered_symbols',
+ '_padding',
+ '_size',
+ '_symbols',
+ '_filtered_symbols',
'name',
'section_name',
+ 'is_sorted',
)
def __init__(self, symbols, filtered_symbols=None, name=None,
- section_name=None):
- self.symbols = symbols
- self.filtered_symbols = filtered_symbols or []
+ section_name=None, is_sorted=False):
+ self._padding = None
+ self._size = None
+ self._symbols = symbols
+ self._filtered_symbols = filtered_symbols or []
self.name = name or ''
self.section_name = section_name or '.*'
+ self.is_sorted = is_sorted
def __repr__(self):
return 'Group(name=%s,count=%d,size=%d)' % (
self.name, len(self), self.size)
def __iter__(self):
- return iter(self.symbols)
+ return iter(self._symbols)
def __len__(self):
- return len(self.symbols)
+ return len(self._symbols)
+
+ def __eq__(self, other):
+ return self._symbols == other._symbols
- def __getitem__(self, index):
- return self.symbols[index]
+ def __getitem__(self, key):
+ """|key| can be an index or an address.
+
+ Raises if multiple symbols map to the address.
+ """
+ if isinstance(key, slice):
+ return self._symbols.__getitem__(key)
+ if isinstance(key, basestring) or key > len(self._symbols):
+ found = self.WhereAddressInRange(key)
+ if len(found) != 1:
+ raise KeyError('%d symbols found at address %s.' % (len(found), key))
+ return found[0]
+ return self._symbols[key]
def __sub__(self, other):
- other_ids = set(id(s) for s in other)
+ if other.IsGroup():
+ other_ids = set(id(s) for s in other)
+ else:
+ other_ids = set((id(other),))
new_symbols = [s for s in self if id(s) not in other_ids]
return self._CreateTransformed(new_symbols, section_name=self.section_name)
def __add__(self, other):
self_ids = set(id(s) for s in self)
- new_symbols = self.symbols + [s for s in other if id(s) not in self_ids]
- return self._CreateTransformed(new_symbols, section_name=self.section_name)
+ new_symbols = self._symbols + [s for s in other if id(s) not in self_ids]
+ return self._CreateTransformed(new_symbols, section_name=self.section_name,
+ is_sorted=False)
@property
def address(self):
@@ -180,21 +213,27 @@ class SymbolGroup(BaseSymbol):
@property
def size(self):
- if self.IsBss():
- return sum(s.size for s in self)
- return sum(s.size for s in self if not s.IsBss())
+ 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())
+ return self._size
@property
def padding(self):
- return sum(s.padding for s in self)
+ if self._padding is None:
+ self._padding = sum(s.padding for s in self)
+ return self._padding
def IsGroup(self):
return True
def _CreateTransformed(self, symbols, filtered_symbols=None, name=None,
- section_name=None):
+ section_name=None, is_sorted=None):
+ if is_sorted is None:
+ is_sorted = self.is_sorted
return SymbolGroup(symbols, filtered_symbols=filtered_symbols, name=name,
- section_name=section_name)
+ section_name=section_name, is_sorted=is_sorted)
def Sorted(self, cmp_func=None, key=None, reverse=False):
# Default to sorting by abs(size) then name.
@@ -202,10 +241,10 @@ class SymbolGroup(BaseSymbol):
cmp_func = lambda a, b: cmp((a.IsBss(), abs(b.size), a.name),
(b.IsBss(), abs(a.size), b.name))
- new_symbols = sorted(self.symbols, cmp_func, key, reverse)
- return self._CreateTransformed(new_symbols,
- filtered_symbols=self.filtered_symbols,
- section_name=self.section_name)
+ new_symbols = sorted(self._symbols, cmp_func, key, reverse)
+ return self._CreateTransformed(
+ new_symbols, filtered_symbols=self._filtered_symbols,
+ section_name=self.section_name, is_sorted=True)
def SortedByName(self, reverse=False):
return self.Sorted(key=(lambda s:s.name), reverse=reverse)
@@ -241,30 +280,57 @@ class SymbolGroup(BaseSymbol):
return self.Filter(lambda s: s.IsGenerated())
def WhereNameMatches(self, pattern):
- regex = re.compile(pattern)
+ regex = re.compile(match_util.ExpandRegexIdentifierPlaceholder(pattern))
return self.Filter(lambda s: regex.search(s.name))
def WhereObjectPathMatches(self, pattern):
- regex = re.compile(pattern)
+ regex = re.compile(match_util.ExpandRegexIdentifierPlaceholder(pattern))
return self.Filter(lambda s: regex.search(s.object_path))
def WhereSourcePathMatches(self, pattern):
- regex = re.compile(pattern)
+ regex = re.compile(match_util.ExpandRegexIdentifierPlaceholder(pattern))
return self.Filter(lambda s: regex.search(s.source_path))
def WherePathMatches(self, pattern):
- regex = re.compile(pattern)
- return self.Filter(lambda s: regex.search(s.source_path or s.object_path))
-
- def WhereAddressInRange(self, start, end):
- return self.Filter(lambda s: s.address >= start and s.address <= end)
+ regex = re.compile(match_util.ExpandRegexIdentifierPlaceholder(pattern))
+ return self.Filter(lambda s: (regex.search(s.source_path) or
+ regex.search(s.object_path)))
+
+ def WhereMatches(self, pattern):
+ """Looks for |pattern| within all paths & names."""
+ regex = re.compile(match_util.ExpandRegexIdentifierPlaceholder(pattern))
+ return self.Filter(lambda s: (regex.search(s.source_path) or
+ regex.search(s.object_path) or
+ regex.search(s.full_name or '') or
+ regex.search(s.name)))
+
+ def WhereAddressInRange(self, start, end=None):
+ """Searches for addesses within [start, end).
+
+ Args may be ints or hex strings. Default value for |end| is |start| + 1.
+ """
+ if isinstance(start, basestring):
+ start = int(start, 16)
+ if end is None:
+ end = start + 1
+ return self.Filter(lambda s: s.address >= start and s.address < end)
def WhereHasAnyAttribution(self):
return self.Filter(lambda s: s.name or s.source_path or s.object_path)
def Inverted(self):
- return self._CreateTransformed(self.filtered_symbols,
- filtered_symbols=self.symbols)
+ """Returns the symbols that were filtered out by the previous filter.
+
+ Applies only when the previous call was a filter.
+
+ Example:
+ # Symbols that do not have "third_party" in their path.
+ symbols.WherePathMatches(r'third_party').Inverted()
+ # Symbols within third_party that do not contain the string "foo".
+ symbols.WherePathMatches(r'third_party').WhereMatches('foo').Inverted()
+ """
+ return self._CreateTransformed(
+ self._filtered_symbols, filtered_symbols=self._symbols, is_sorted=False)
def GroupBy(self, func, min_count=0):
"""Returns a SymbolGroup of SymbolGroups, indexed by |func|.
@@ -292,14 +358,16 @@ class SymbolGroup(BaseSymbol):
min_count = abs(min_count)
for token, symbols in symbols_by_token.iteritems():
if len(symbols) >= min_count:
- new_syms.append(self._CreateTransformed(symbols, name=token,
- section_name=self.section_name))
+ new_syms.append(self._CreateTransformed(
+ symbols, name=token, section_name=self.section_name,
+ is_sorted=False))
elif include_singles:
new_syms.extend(symbols)
else:
filtered_symbols.extend(symbols)
- return self._CreateTransformed(new_syms, filtered_symbols=filtered_symbols,
- section_name=self.section_name)
+ return self._CreateTransformed(
+ new_syms, filtered_symbols=filtered_symbols,
+ section_name=self.section_name, is_sorted=False)
def GroupBySectionName(self):
return self.GroupBy(lambda s: s.section_name)
@@ -402,18 +470,18 @@ class SymbolDiff(SymbolGroup):
self.unchanged_count, self.size)
def _CreateTransformed(self, symbols, filtered_symbols=None, name=None,
- section_name=None):
+ section_name=None, is_sorted=None):
ret = SymbolDiff.__new__(SymbolDiff)
# Printing sorts, so fast-path the same symbols case.
- if len(symbols) == len(self.symbols):
+ if len(symbols) == len(self._symbols):
ret._added_ids = self._added_ids
ret._removed_ids = self._removed_ids
else:
ret._added_ids = set(id(s) for s in symbols if self.IsAdded(s))
ret._removed_ids = set(id(s) for s in symbols if self.IsRemoved(s))
- super(SymbolDiff, ret).__init__(symbols, filtered_symbols=filtered_symbols,
- name=name, section_name=section_name)
-
+ super(SymbolDiff, ret).__init__(
+ symbols, filtered_symbols=filtered_symbols, name=name,
+ section_name=section_name, is_sorted=is_sorted)
return ret
@property
« no previous file with comments | « tools/binary_size/match_util_test.py ('k') | tools/binary_size/testdata/ActualDiff.golden » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698