Chromium Code Reviews| Index: tools/binary_size/libsupersize/cluster_symbols.py |
| diff --git a/tools/binary_size/libsupersize/cluster_symbols.py b/tools/binary_size/libsupersize/cluster_symbols.py |
| index 2c1f407da43b3c9b4e301100373f07c2bb026c2d..672c777fed6ef9416ef3beb8b5d9850994a74db7 100644 |
| --- a/tools/binary_size/libsupersize/cluster_symbols.py |
| +++ b/tools/binary_size/libsupersize/cluster_symbols.py |
| @@ -8,8 +8,18 @@ import collections |
| import logging |
| import re |
| +import function_signature |
| -# Refer to models.SymbolGroup.Cluster() for pydoc |
| + |
| +def _StripCloneSuffix(name): |
| + # Multiple attributes could exist, so search from left-to-right. |
| + idx = name.find(' [clone ') |
| + if idx != -1: |
| + return name[:idx] |
| + return name |
| + |
| + |
| +# Refer to models.SymbolGroup.Clustered() for pydoc |
| def ClusterSymbols(symbols): |
| # http://unix.stackexchange.com/questions/223013/function-symbol-gets-part-suffix-after-compilation |
| # Example name suffixes: |
| @@ -22,40 +32,40 @@ def ClusterSymbols(symbols): |
| logging.debug('Creating name -> symbol map') |
| clone_indices = [] |
| indices_by_full_name = {} |
| - # (section_name, name, full_name) -> [(index, sym),...] |
| + # (section_name, full_name_no_attr) -> [(index, sym),...] |
| replacements_by_tup = collections.defaultdict(list) |
| for i, symbol in enumerate(symbols): |
| - if symbol.name.startswith('**'): |
| + name = symbol.full_name |
| + if not name: |
| + continue |
| + if name.startswith('*'): |
| # "symbol gap 3" -> "symbol gaps" |
| - name = re.sub(r'\s+\d+( \(.*\))?$', 's', symbol.name) |
| - replacements_by_tup[(symbol.section_name, name, None)].append((i, symbol)) |
| - elif symbol.full_name: |
| - if symbol.full_name.endswith(']') and ' [clone ' in symbol.full_name: |
| - clone_indices.append(i) |
| - else: |
| - indices_by_full_name[symbol.full_name] = i |
| + name = re.sub(r'\s+\d+( \(.*\))?$', 's', name) |
| + replacements_by_tup[(symbol.section_name, name)].append((i, symbol)) |
| + elif name.endswith(']') and ' [clone ' in name: |
| + clone_indices.append(i) |
| + else: |
| + indices_by_full_name[name] = i |
| # Step 2: Collect same-named clone symbols. |
| logging.debug('Grouping all clones') |
| group_names_by_index = {} |
| for i in clone_indices: |
| symbol = symbols[i] |
| - # Multiple attributes could exist, so search from left-to-right. |
| - stripped_name = symbol.name[:symbol.name.index(' [clone ')] |
| - stripped_full_name = symbol.full_name[:symbol.full_name.index(' [clone ')] |
| - name_tup = (symbol.section_name, stripped_name, stripped_full_name) |
| + stripped_full_name = _StripCloneSuffix(symbol.full_name) |
| + name_tup = (symbol.section_name, stripped_full_name) |
| replacement_list = replacements_by_tup[name_tup] |
| if not replacement_list: |
| # First occurance, check for non-clone symbol. |
| - non_clone_idx = indices_by_full_name.get(stripped_name) |
| + non_clone_idx = indices_by_full_name.get(stripped_full_name) |
| if non_clone_idx is not None: |
| non_clone_symbol = symbols[non_clone_idx] |
| replacement_list.append((non_clone_idx, non_clone_symbol)) |
| - group_names_by_index[non_clone_idx] = stripped_name |
| + group_names_by_index[non_clone_idx] = stripped_full_name |
| replacement_list.append((i, symbol)) |
| - group_names_by_index[i] = stripped_name |
| + group_names_by_index[i] = stripped_full_name |
| # Step 3: Undo clustering when length=1. |
| # Removing these groups means Diff() logic must know about [clone] suffix. |
| @@ -77,14 +87,13 @@ def ClusterSymbols(symbols): |
| dest_index = 0 |
| src_index = 0 |
| seen_tups = set() |
| - replacement_tup_by_index = {} |
| + index_and_name_tups = [] |
|
estevenson
2017/05/09 22:15:12
I find this function hard to grok, basically had t
agrieve
2017/05/10 00:51:38
likewise. For now I've just added a TODO comment t
|
| for name_tup, replacement_list in replacements_by_tup.iteritems(): |
| - for tup in replacement_list: |
| - replacement_tup_by_index[tup[0]] = name_tup |
| + for symbol_tup in replacement_list: |
| + index_and_name_tups.append((symbol_tup[0], name_tup)) |
| - sorted_items = replacement_tup_by_index.items() |
| - sorted_items.sort(key=lambda tup: tup[0]) |
| - for index, name_tup in sorted_items: |
| + index_and_name_tups.sort(key=lambda tup: tup[0]) |
| + for index, name_tup in index_and_name_tups: |
| count = index - src_index |
| grouped_symbols[dest_index:dest_index + count] = ( |
| symbols[src_index:src_index + count]) |
| @@ -93,9 +102,20 @@ def ClusterSymbols(symbols): |
| if name_tup not in seen_tups: |
| seen_tups.add(name_tup) |
| group_symbols = [tup[1] for tup in replacements_by_tup[name_tup]] |
| - grouped_symbols[dest_index] = symbols._CreateTransformed( |
| - group_symbols, name=name_tup[1], full_name=name_tup[2], |
| - section_name=name_tup[0]) |
| + section_name, stripped_full_name = name_tup |
| + if stripped_full_name.startswith('*'): |
| + stripped_template_name = stripped_full_name |
| + stripped_name = stripped_full_name |
| + else: |
| + stripped_template_name = _StripCloneSuffix( |
| + group_symbols[0].template_name) |
| + stripped_name = _StripCloneSuffix(group_symbols[0].name) |
| + cluster = symbols._CreateTransformed( |
| + group_symbols, full_name=stripped_full_name, |
| + template_name=stripped_template_name, name=stripped_name, |
| + section_name=section_name) |
| + function_signature.InternSameNames(cluster) |
| + grouped_symbols[dest_index] = cluster |
| dest_index += 1 |
| assert len(grouped_symbols[dest_index:None]) == len(symbols[src_index:None]) |