File: canned_queries.py

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (208 lines) | stat: -rw-r--r-- 8,616 bytes parent folder | download | duplicates (10)
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()