Chromium Code Reviews| Index: tools/binary_size/run_binary_size_analysis.py |
| diff --git a/tools/binary_size/run_binary_size_analysis.py b/tools/binary_size/run_binary_size_analysis.py |
| index 7647a22dcb69b351b429f0e6e35911dd39e1b8be..a6ab4976c92a8fccc31bfae95f085613bac5ce14 100755 |
| --- a/tools/binary_size/run_binary_size_analysis.py |
| +++ b/tools/binary_size/run_binary_size_analysis.py |
| @@ -61,32 +61,107 @@ def SymbolTypeToHuman(symbol_type): |
| 'w': 'weak symbol', |
| 'v': 'weak symbol'}[symbol_type] |
| +# Node dictionary keys. These are output in json read by the webapp so |
| +# keep them short to save file size. |
| +# Note: If these change, the webapp must also change. |
| +NODE_TYPE_KEY = 'k' |
|
Primiano Tucci (use gerrit)
2014/05/27 09:24:17
Globals and constatns should go between imports an
Daniel Bratell
2014/06/04 13:04:45
Done.
|
| +NODE_NAME_KEY = 'n' |
| +NODE_CHILDREN_KEY = 'children' |
| +NODE_SYMBOL_TYPE_KEY = 't' |
| +NODE_SYMBOL_SIZE_KEY = 'value' |
| +NODE_MAX_DEPTH_KEY = 'maxDepth' |
| +NODE_LAST_PATH_ELEMENT_KEY = 'lastPathElement' |
| def _MkChild(node, name): |
| - child = node['children'].get(name) |
| + child = node[NODE_CHILDREN_KEY].get(name) |
|
Primiano Tucci (use gerrit)
2014/05/27 09:24:17
To be honest, sounds like your nodes should start
Daniel Bratell
2014/06/04 13:04:45
I agree, but I'd prefer to postpone that change to
|
| if child is None: |
| - child = {'n': name, 'children': {}} |
| - node['children'][name] = child |
| + child = {NODE_NAME_KEY: name, |
| + NODE_CHILDREN_KEY: {}} |
| + node[NODE_CHILDREN_KEY][name] = child |
| return child |
| +BIG_BUCKET_LIMIT = 2000 |
|
Primiano Tucci (use gerrit)
2014/05/27 09:24:17
Ditto. Globals should live all together happily in
Andrew Hayden (chromium.org)
2014/05/27 10:04:11
Minor nit, the review says 3k and this constant is
Daniel Bratell
2014/06/04 13:04:45
Done.
Daniel Bratell
2014/06/04 13:04:45
Done.
|
| + |
| + |
| +def SplitNoPathBucket(node): |
| + """(No Path) can be too large for the graphing lib to handle. Split |
| + it into sub-buckets in that case.""" |
| + root_children = node[NODE_CHILDREN_KEY] |
| + if '(No Path)' in root_children: |
|
Andrew Hayden (chromium.org)
2014/05/27 10:04:11
We should probably extract the string "(No Path)"
Daniel Bratell
2014/06/04 13:04:45
Done.
|
| + no_path_bucket = root_children['(No Path)'] |
| + old_children = no_path_bucket[NODE_CHILDREN_KEY] |
| + count = 0 |
| + for symbol_type, symbol_bucket in old_children.iteritems(): |
| + count += len(symbol_bucket[NODE_CHILDREN_KEY]) |
| + if count > BIG_BUCKET_LIMIT: |
| + new_children = {} |
| + no_path_bucket[NODE_CHILDREN_KEY] = new_children |
| + current_bucket = None |
| + index = 0 |
| + for symbol_type, symbol_bucket in old_children.iteritems(): |
| + for symbol_name, value in symbol_bucket[NODE_CHILDREN_KEY].iteritems(): |
| + if index % BIG_BUCKET_LIMIT == 0: |
| + group_no = (index / BIG_BUCKET_LIMIT) + 1 |
| + current_bucket = _MkChild(no_path_bucket, |
| + '(No Path) subgroup %d' % group_no) |
| + assert not NODE_TYPE_KEY in node or node[NODE_TYPE_KEY] == 'p' |
| + node[NODE_TYPE_KEY] = 'p' # p for path |
| + index += 1 |
| + symbol_size = value[NODE_SYMBOL_SIZE_KEY] |
| + AddSymbolIntoFileNode(current_bucket, symbol_type, |
| + symbol_name, symbol_size) |
| + no_path_bucket[NODE_CHILDREN_KEY] = new_children |
|
Primiano Tucci (use gerrit)
2014/05/27 09:24:17
Uh? Looks like you already did this on line 99? Or
Daniel Bratell
2014/06/04 13:04:45
Yes, duplicate assignments. Fixed.
|
| + |
| + |
| def MakeChildrenDictsIntoLists(node): |
| largest_list_len = 0 |
| - if 'children' in node: |
| - largest_list_len = len(node['children']) |
| + if NODE_CHILDREN_KEY in node: |
| + largest_list_len = len(node[NODE_CHILDREN_KEY]) |
| child_list = [] |
| - for child in node['children'].itervalues(): |
| + for child in node[NODE_CHILDREN_KEY].itervalues(): |
| child_largest_list_len = MakeChildrenDictsIntoLists(child) |
| if child_largest_list_len > largest_list_len: |
| largest_list_len = child_largest_list_len |
| child_list.append(child) |
| - node['children'] = child_list |
| + node[NODE_CHILDREN_KEY] = child_list |
| return largest_list_len |
| +def AddSymbolIntoFileNode(node, symbol_type, symbol_name, symbol_size): |
| + """Puts symbol into the file path node |node|. Returns the number of |
|
Primiano Tucci (use gerrit)
2014/05/27 09:24:17
Nit: the first line of a docstring should fit in o
Daniel Bratell
2014/06/04 13:04:45
They are always of height 2. :-)
This is extracte
|
| + added levels in tree. I.e. returns 2.""" |
| + |
| + depth = 0 |
|
Andrew Hayden (chromium.org)
2014/05/27 10:04:11
From a clarity standpoint I'd prefer if we avoid t
Daniel Bratell
2014/06/04 13:04:45
Done.
|
| + |
| + # 'node' is now the file node. Find the symbol-type bucket. |
|
Andrew Hayden (chromium.org)
2014/05/27 10:04:11
The first part of this comment made sense in-situ,
Daniel Bratell
2014/06/04 13:04:45
Done.
|
| + node[NODE_LAST_PATH_ELEMENT_KEY] = True |
| + node = _MkChild(node, symbol_type) |
| + assert not NODE_TYPE_KEY in node or node[NODE_TYPE_KEY] == 'b' |
| + node[NODE_SYMBOL_TYPE_KEY] = symbol_type |
| + node[NODE_TYPE_KEY] = 'b' # b for bucket |
| + depth += 1 |
| + |
| + # 'node' is now the symbol-type bucket. Make the child entry. |
| + node = _MkChild(node, symbol_name) |
| + if NODE_CHILDREN_KEY in node: |
| + if node[NODE_CHILDREN_KEY]: |
| + logging.warning('A container node used as symbol for %s.' % symbol_name) |
| + # This is going to be used as a leaf so no use for child list. |
| + del node[NODE_CHILDREN_KEY] |
| + node[NODE_SYMBOL_SIZE_KEY] = symbol_size |
| + node[NODE_SYMBOL_TYPE_KEY] = symbol_type |
| + node[NODE_TYPE_KEY] = 's' # s for symbol |
| + depth += 1 |
| + return depth |
| + |
| + |
| def MakeCompactTree(symbols): |
| - result = {'n': '/', 'children': {}, 'k': 'p', 'maxDepth': 0} |
| + result = {NODE_NAME_KEY: '/', |
| + NODE_CHILDREN_KEY: {}, |
| + NODE_TYPE_KEY: 'p', |
| + NODE_MAX_DEPTH_KEY: 0} |
| seen_symbol_with_path = False |
| for symbol_name, symbol_type, symbol_size, file_path in symbols: |
| @@ -112,36 +187,22 @@ def MakeCompactTree(symbols): |
| continue |
| depth += 1 |
| node = _MkChild(node, path_part) |
| - assert not 'k' in node or node['k'] == 'p' |
| - node['k'] = 'p' # p for path |
| - |
| - # 'node' is now the file node. Find the symbol-type bucket. |
| - node['lastPathElement'] = True |
| - node = _MkChild(node, symbol_type) |
| - assert not 'k' in node or node['k'] == 'b' |
| - node['t'] = symbol_type |
| - node['k'] = 'b' # b for bucket |
| - depth += 1 |
| - |
| - # 'node' is now the symbol-type bucket. Make the child entry. |
| - node = _MkChild(node, symbol_name) |
| - if 'children' in node: |
| - if node['children']: |
| - logging.warning('A container node used as symbol for %s.' % symbol_name) |
| - # This is going to be used as a leaf so no use for child list. |
| - del node['children'] |
| - node['value'] = symbol_size |
| - node['t'] = symbol_type |
| - node['k'] = 's' # s for symbol |
| - depth += 1 |
| - result['maxDepth'] = max(result['maxDepth'], depth) |
| + assert not NODE_TYPE_KEY in node or node[NODE_TYPE_KEY] == 'p' |
| + node[NODE_TYPE_KEY] = 'p' # p for path |
|
Primiano Tucci (use gerrit)
2014/05/27 09:24:17
Nit: add an extra space before #
|
| + |
| + depth += AddSymbolIntoFileNode(node, symbol_type, symbol_name, symbol_size) |
| + result[NODE_MAX_DEPTH_KEY] = max(result[NODE_MAX_DEPTH_KEY], depth) |
| if not seen_symbol_with_path: |
| logging.warning('Symbols lack paths. Data will not be structured.') |
| + # The (no path) bucket can be extremely large if we failed to get |
| + # path information. Split it into subgroups if needed. |
| + SplitNoPathBucket(result) |
| + |
| largest_list_len = MakeChildrenDictsIntoLists(result) |
| - if largest_list_len > 1000: |
| + if largest_list_len > BIG_BUCKET_LIMIT: |
| logging.warning('There are sections with %d nodes. ' |
| 'Results might be unusable.' % largest_list_len) |
| return result |