1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
# Copyright 2017 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Contains a set of Chrome-specific size queries."""
import logging
import re
import models
class _Grouper:
def __init__(self):
self.groups = []
def Add(self, name, group):
logging.debug('Computed %s (%d syms)', name, len(group))
if group:
sorted_group = group.Sorted()
sorted_group.SetName(name)
self.groups.append(sorted_group)
return group.Inverted()
def Finalize(self, remaining):
self.groups.sort(key=lambda s:(s.name.startswith('Other'), -abs(s.pss)))
if remaining:
stars = remaining.Filter(lambda s: s.name.startswith('*'))
if stars:
remaining = stars.Inverted()
stars = stars.Sorted()
stars.SetName('** Merged Symbols')
self.groups.append(stars)
others_by_path = remaining.GroupedByPath(depth=1).Sorted()
for subgroup in others_by_path:
subgroup.SetName('Other //' + subgroup.name)
self.groups.extend(others_by_path)
logging.debug('Finalized')
return models.SymbolGroup(self.groups)
def _CategorizeByChromeComponent(symbols):
g = _Grouper()
# Put things that filter out a lot of symbols at the beginning where possible
# to optimize speed.
symbols = g.Add('WebRTC', symbols.WhereMatches(r'(?i)webrtc'))
symbols = g.Add('v8', symbols.Filter(
lambda s: s.source_path.startswith('v8/')))
symbols = g.Add('Skia', symbols.Filter(lambda s: 'skia/' in s.source_path))
symbols = g.Add('net', symbols.Filter(
lambda s: s.source_path.startswith('net/')))
symbols = g.Add('media', symbols.Filter(
lambda s: s.source_path.startswith('media/')))
symbols = g.Add('gpu', symbols.Filter(
lambda s: s.source_path.startswith('gpu/')))
symbols = g.Add('cc', symbols.Filter(
lambda s: s.source_path.startswith('cc/')))
symbols = g.Add('base', symbols.Filter(
lambda s: s.source_path.startswith('base/')))
symbols = g.Add('viz', symbols.Filter(
lambda s: s.source_path.startswith('components/viz')))
symbols = g.Add('ui/gfx', symbols.Filter(
lambda s: s.source_path.startswith('ui/gfx/')))
# Next, put non-regex queries, since they're a bit faster.
symbols = g.Add('ICU', symbols.Filter(lambda s: '/icu/' in s.source_path))
symbols = g.Add('Prefetch', symbols.Filter(
lambda s: 'resource_prefetch' in s.source_path))
symbols = g.Add('Password Manager', symbols.Filter(
lambda s: 'password_manager' in s.source_path))
symbols = g.Add('Internals Pages', symbols.Filter(
lambda s: '_internals' in s.source_path))
symbols = g.Add('Autofill', symbols.WhereSourcePathMatches(r'(?i)autofill'))
symbols = g.Add('WebGL', symbols.WhereMatches(r'(?i)webgl'))
symbols = g.Add('WebBluetooth', symbols.WhereMatches(r'(?i)bluetooth'))
symbols = g.Add('WebUSB', symbols.WhereMatches(r'(?i)webusb|(\b|_)usb(\b|_)'))
symbols = g.Add('WebVR', symbols.WhereMatches(
r'{{_gvr_}}|{{_cwebvr_}}|{{_vr_}}'))
symbols = g.Add('FileSystem', symbols.WhereSourcePathMatches(
r'content/.*/fileapi|WebKit/.*/filesystem'))
symbols = g.Add('WebCrypto', symbols.WhereMatches(r'(?i)webcrypto'))
symbols = g.Add('Printing', symbols.WhereMatches(r'printing'))
symbols = g.Add('Cast', symbols.WhereSourcePathMatches(
r'(?i)(\b|_)cast(\b|_)'))
symbols = g.Add('Media Source', symbols.WhereMatches(
r'(?i)mediasource|blink::.*TrackDefault|blink::.*SourceBuffer'))
# XSLT must come before libxml.
symbols = g.Add('XSLT', symbols.WhereMatches(r'(?i)xslt'))
symbols = g.Add('libxml', symbols.Filter(
lambda s: 'libxml' in s.source_path))
# These have some overlap with above, so need to come afterwards.
blink_syms = symbols.WhereSourcePathMatches(r'\b(blink|WebKit)\b')
symbols = blink_syms.Inverted()
blink_generated = blink_syms.WhereSourceIsGenerated()
g.Add('Blink (generated)', blink_generated)
g.Add('Blink (non-generated)', blink_generated.Inverted())
symbols = g.Add('Codecs', symbols.WhereSourcePathMatches(
r'^third_party/(libweb[mp]|libpng|libjpeg_turbo|opus|ffmpeg|libvpx)/'))
symbols = g.Add('Other Third-Party', symbols.Filter(
lambda s: 'third_party' in s.source_path))
return g.Finalize(symbols)
def _CategorizeGenerated(symbols):
g = _Grouper()
# Don't count other symbols or prebuilts.
symbols = symbols.Filter(lambda s: s.section_name != models.SECTION_OTHER and
not s.source_path.endswith('.class'))
# JNI is generated into .h files then #included, so the symbols don't actaully
# appear as "SourceIsGenerated".
# Note: String literals within symbols like "kBaseRegisteredMethods" are not
# being accounted for here because they end up within "** merge strings".
# This could be fixed by assigning them all to proper variables rather
# than having them be inline.
symbols = g.Add('RegisterJNI', symbols.WhereFullNameMatches(
r'Register.*JNIEnv\*\)|RegisteredMethods$'))
symbols = g.Add('gl_bindings_autogen',
symbols.WherePathMatches('gl_bindings_autogen'))
symbols = symbols.WhereSourceIsGenerated()
symbols = g.Add(
'Java Protocol Buffers',
symbols.Filter(lambda s: '__protoc_java.srcjar' in s.source_path))
symbols = g.Add('C++ Protocol Buffers', symbols.Filter(lambda s: (
'/protobuf/' in s.object_path or
s.object_path.endswith('.pbzero.o') or
s.object_path.endswith('.pb.o'))))
mojo_pattern = re.compile(r'\bmojom?\b')
symbols = g.Add(
'Mojo',
symbols.Filter(lambda s: (s.full_name.startswith('mojo::') or mojo_pattern
.search(s.source_path))))
symbols = g.Add('DevTools', symbols.WhereSourcePathMatches(
r'\b(?:protocol|devtools)\b'))
symbols = g.Add('Blink (bindings)', symbols.WherePathMatches(
r'(?:blink|WebKit)/.*bindings'))
symbols = g.Add('Blink (other)', symbols.Filter(lambda s: (
'WebKit' in s.object_path or 'blink/' in s.object_path)))
symbols = g.Add('V8 Builtins', symbols.Filter(lambda s: (
s.source_path.endswith('embedded.S'))))
symbols = g.Add('prepopulated_engines.cc', symbols.Filter(lambda s: (
'prepopulated_engines' in s.object_path)))
symbols = g.Add('Metrics-related code', symbols.Filter(lambda s: (
'/metrics/' in s.object_path)))
symbols = g.Add('gpu_driver_bug_list_autogen.cc', symbols.Filter(lambda s: (
'gpu_driver_bug_list' in s.object_path)))
symbols = g.Add('components/policy', symbols.Filter(lambda s: (
'components/policy' in s.object_path)))
return g.Finalize(symbols)
class CannedQueries:
"""A set of pre-written queries."""
def __init__(self, size_infos):
self._size_infos = size_infos
def _SymbolsArg(self, arg, native_only=False, pak_only=False):
arg = arg if arg is not None else self._size_infos[-1]
if isinstance(arg, models.BaseSizeInfo):
if native_only:
arg = arg.native_symbols
elif pak_only:
arg = arg.pak_symbols
else:
arg = arg.symbols
return arg
def CategorizeGenerated(self, symbols=None):
"""Categorizes symbols that come from generated source files."""
return _CategorizeGenerated(self._SymbolsArg(symbols))
def CategorizeByChromeComponent(self, symbols=None):
"""Groups symbols by component using predefined queries."""
return _CategorizeByChromeComponent(self._SymbolsArg(symbols))
def TemplatesByName(self, symbols=None, depth=0):
"""Lists C++ templates grouped by name."""
symbols = self._SymbolsArg(symbols, native_only=True)
# Call Sorted() twice so that subgroups will be sorted.
# TODO(agrieve): Might be nice to recursively GroupedByName() on these.
return symbols.WhereIsTemplate().Sorted().GroupedByName(depth).Sorted()
def StaticInitializers(self, symbols=None):
"""Lists Static Initializers."""
symbols = self._SymbolsArg(symbols, native_only=True)
# GCC generates "_GLOBAL__" symbols. Clang generates "startup".
return symbols.WhereNameMatches('^startup$|^_GLOBAL__')
def LargeFiles(self, symbols=None, min_size=50 * 1024):
"""Lists source files that are larger than a certain size (default 50kb)."""
symbols = self._SymbolsArg(symbols)
return symbols.GroupedByPath(fallback=None).WherePssBiggerThan(
min_size).Sorted()
def PakByPath(self, symbols=None):
"""Groups .pak.* symbols by path."""
symbols = self._SymbolsArg(symbols, pak_only=True)
return symbols.WhereIsPak().Sorted().GroupedByPath().Sorted()
|