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

Side by Side Diff: tools/binary_size/libsupersize/cluster_symbols.py

Issue 2854173003: supersize: Don't cluster by default. Make Diff() accept only SizeInfo. (Closed)
Patch Set: Created 3 years, 7 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 unified diff | Download patch
« no previous file with comments | « tools/binary_size/libsupersize/archive.py ('k') | tools/binary_size/libsupersize/describe.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2017 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Logic for clustering similar symbols."""
6
7 import collections
8 import logging
9 import re
10
11
12 # Refer to models.SymbolGroup.Cluster() for pydoc
13 def ClusterSymbols(symbols):
14 # http://unix.stackexchange.com/questions/223013/function-symbol-gets-part-suf fix-after-compilation
15 # Example name suffixes:
16 # [clone .part.322] # GCC
17 # [clone .isra.322] # GCC
18 # [clone .constprop.1064] # GCC
19 # [clone .11064] # clang
20
21 # Step 1: Create name map, find clones, collect star syms into replacements.
22 logging.debug('Creating name -> symbol map')
23 clone_indices = []
24 indices_by_full_name = {}
25 # (name, full_name) -> [(index, sym),...]
26 replacements_by_name = collections.defaultdict(list)
27 for i, symbol in enumerate(symbols):
28 if symbol.name.startswith('**'):
29 # "symbol gap 3" -> "symbol gaps"
30 name = re.sub(r'\s+\d+$', 's', symbol.name)
31 replacements_by_name[(name, None)].append((i, symbol))
32 elif symbol.full_name:
33 if symbol.full_name.endswith(']') and ' [clone ' in symbol.full_name:
34 clone_indices.append(i)
35 else:
36 indices_by_full_name[symbol.full_name] = i
37
38 # Step 2: Collect same-named clone symbols.
39 logging.debug('Grouping all clones')
40 group_names_by_index = {}
41 for i in clone_indices:
42 symbol = symbols[i]
43 # Multiple attributes could exist, so search from left-to-right.
44 stripped_name = symbol.name[:symbol.name.index(' [clone ')]
45 stripped_full_name = symbol.full_name[:symbol.full_name.index(' [clone ')]
46 name_tup = (stripped_name, stripped_full_name)
47 replacement_list = replacements_by_name[name_tup]
48
49 if not replacement_list:
50 # First occurance, check for non-clone symbol.
51 non_clone_idx = indices_by_full_name.get(stripped_name)
52 if non_clone_idx is not None:
53 non_clone_symbol = symbols[non_clone_idx]
54 replacement_list.append((non_clone_idx, non_clone_symbol))
55 group_names_by_index[non_clone_idx] = stripped_name
56
57 replacement_list.append((i, symbol))
58 group_names_by_index[i] = stripped_name
59
60 # Step 3: Undo clustering when length=1.
61 # Removing these groups means Diff() logic must know about [clone] suffix.
62 to_clear = []
63 for name_tup, replacement_list in replacements_by_name.iteritems():
64 if len(replacement_list) == 1:
65 to_clear.append(name_tup)
66 for name_tup in to_clear:
67 del replacements_by_name[name_tup]
68
69 # Step 4: Replace first symbol from each cluster with a SymbolGroup.
70 before_symbol_count = sum(len(x) for x in replacements_by_name.itervalues())
71 logging.debug('Creating %d symbol groups from %d symbols. %d clones had only '
72 'one symbol.', len(replacements_by_name), before_symbol_count,
73 len(to_clear))
74
75 len_delta = len(replacements_by_name) - before_symbol_count
76 grouped_symbols = [None] * (len(symbols) + len_delta)
77 dest_index = 0
78 src_index = 0
79 seen_names = set()
80 replacement_names_by_index = {}
81 for name_tup, replacement_list in replacements_by_name.iteritems():
82 for tup in replacement_list:
83 replacement_names_by_index[tup[0]] = name_tup
84
85 sorted_items = replacement_names_by_index.items()
86 sorted_items.sort(key=lambda tup: tup[0])
87 for index, name_tup in sorted_items:
88 count = index - src_index
89 grouped_symbols[dest_index:dest_index + count] = (
90 symbols[src_index:src_index + count])
91 src_index = index + 1
92 dest_index += count
93 if name_tup not in seen_names:
94 seen_names.add(name_tup)
95 group_symbols = [tup[1] for tup in replacements_by_name[name_tup]]
96 grouped_symbols[dest_index] = symbols._CreateTransformed(
97 group_symbols, name=name_tup[0], full_name=name_tup[1],
98 section_name=group_symbols[0].section_name)
99 dest_index += 1
100
101 assert len(grouped_symbols[dest_index:None]) == len(symbols[src_index:None])
102 grouped_symbols[dest_index:None] = symbols[src_index:None]
103 logging.debug('Finished clustering symbols.')
104 return grouped_symbols
OLDNEW
« no previous file with comments | « tools/binary_size/libsupersize/archive.py ('k') | tools/binary_size/libsupersize/describe.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698