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

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

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