These tools currently focus on Android. They somewhat work with Linux builds, but not as well. As for Windows, some great tools already exist and are documented here:
There is also a dedicated mailing-list for binary size discussions:
Bugs are tracked here:
Determine the cause of binary size bloat between two commits. Works for Android and Linux (although Linux symbol diffs have issues, as noted below).
.size
files from perf bots (--cloud
)resource_size.py
and supersize
.# Build and diff HEAD^ and HEAD. tools/binary_size/diagnose_bloat.py HEAD -v # Diff BEFORE_REV and AFTER_REV using build artifacts downloaded from perf bots. tools/binary_size/diagnose_bloat.py AFTER_REV --reference-rev BEFORE_REV --cloud -v # Fetch a .size, libmonochrome.so, and MonochromePublic.apk from perf bots (Googlers only): tools/binary_size/diagnose_bloat.py AFTER_REV --cloud --unstripped --single # Build and diff all contiguous revs in range BEFORE_REV..AFTER_REV for src/v8. tools/binary_size/diagnose_bloat.py AFTER_REV --reference-rev BEFORE_REV --subrepo v8 --all -v # Display detailed usage info (there are many options). tools/binary_size/diagnose_bloat.py -h
Collect, archive, and analyze Chrome's binary size. Supports Android and Linux (although Linux has issues).
.size
files are archived on perf builders so that regressions can be quickly analyzed (via diagnose_bloat.py --cloud
).
.size
files are archived on official builders so that symbols can be diff'ed between milestones.
.size
files are gzipped plain text files that contain:
readelf -S
,.o
/ .cc
files..map
file.nm
output, such as ** merge strings
entries, and some unnamed symbols (which although unnamed, contain the .o
path)..o
files are mapped to .cc
files by parsing .ninja
files..h
files are never listed as sources. No information about inlined symbols is gathered.nm elf-file
..pss
as .size / .num_aliases
.** merge strings
symbols are further broken down into individual string literal symbols. This is done by reading string literals from .o
files, and then searching for them within the ** merge strings
sections..o
files. These include inline functions defined in .h
files, and string literals that are de-duped at link-time. Shared symbols are normally represented using one symbol alias per path, but are sometimes collapsed into a single symbol where the path is set to {shared}/$SYMBOL_COUNT
. This collapsing is done only for symbols owned by a large number of paths.Path normalization:
out/Release/
, gen/
, obj/
foo/bar.a(baz.o)
-> foo/bar.a/baz.o
base/{shared}/3
(the “3” means three different files contain the symbol)Name normalization:
(anonymous::)
is removed from names (and stored as a symbol flag).[clone]
suffix removed (and stored as a symbol flag).vtable for FOO
-> Foo [vtable]
name
: Name without template and argument parameterstemplate_name
: Name without argument parameters.full_name
: Name with all parameters.Clustering
[clone]
” (removed by normalization).SizeInfo.symbols
. To view unclustered symbols, use SizeInfo.raw_symbols
.Diffing
No. Most of the logic is would could work for any ELF executable. However, being a generic tool is not a goal. Some examples of existing Chrome-specific logic:
.ninja
build rules are available..so
given .apk
..pak
file analysis.Collect size information and dump it into a .size
file.
Note: Refer to diagnose_bloat.py for list of GN args to build a Release binary (or just use the tool with --single).
Googlers: If you just want a .size
for a commit on master:
GIT_REV="HEAD~200" tools/binary_size/diagnose_bloat.py --single --cloud --unstripped $GIT_REV
Example Usage:
# Android: ninja -C out/Release -j 1000 apks/ChromePublic.apk tools/binary_size/supersize archive chrome.size --apk-file out/Release/apks/ChromePublic.apk -v # Linux: ninja -C out/Release -j 1000 chrome tools/binary_size/supersize archive chrome.size --elf-file out/Release/chrome -v
Creates an interactive size breakdown (by source path) as a stand-alone html report.
Example output: https://agrieve.github.io/chrome/
Example Usage:
tools/binary_size/supersize html_report chrome.size --report-dir size-report -v xdg-open size-report/index.html
A convenience command equivalent to: console before.size after.size --query='Print(Diff(size_info1, size_info2))'
Example Usage:
tools/binary_size/supersize diff before.size after.size --all
Starts a Python interpreter where you can run custom queries, or run pre-made queries from canned_queries.py
.
Example Usage:
# Prints size infomation and exits (does not enter interactive mode). tools/binary_size/supersize console chrome.size --query='Print(size_info)' # Enters a Python REPL (it will print more guidance). tools/binary_size/supersize console chrome.size
Example session:
>>> ShowExamples() # Get some inspiration. ... >>> sorted = size_info.symbols.WhereInSection('t').Sorted() >>> Print(sorted) # Have a look at the largest symbols. ... >>> sym = sorted.WhereNameMatches('TrellisQuantizeBlock')[0] >>> Disassemble(sym) # Time to learn assembly. ... >>> help(canned_queries) ... >>> Print(canned_queries.TemplatesByName(depth=-1)) ... >>> syms = size_info.symbols.WherePathMatches(r'skia').Sorted() >>> Print(syms, verbose=True) # Show full symbol names with parameter types. ... >>> # Dump all string literals from skia files to "strings.txt". >>> Print((t[1] for t in ReadStringLiterals(syms)), to_file='strings.txt')
archive
features:console
features:SplitByName()
- Like GroupByName()
, but recursive.html_report
features:SplitByName()
)resource_sizes.py
so that it tracks size of major components separately: chrome vs blink vs skia vs v8.tools\win\linker_verbose_tracking.py