Skip to content

Commit 2118f18

Browse files
[tools] Consume bloaty's output instead of nm for binary size analysis.
This makes the attribution of file bytes much more exhaustive. Change-Id: Ie582b30cc0fb72f84ace447e88581b5759134d82 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423764 Reviewed-by: Brian Quinlan <[email protected]>
1 parent b69b2c8 commit 2118f18

File tree

1 file changed

+30
-116
lines changed

1 file changed

+30
-116
lines changed

runtime/tools/binary_size

Lines changed: 30 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -71,33 +71,6 @@ const filteredPathComponents = <String>[
7171
"ProductXARM64",
7272
];
7373

74-
const filteredSections = <String>[
75-
// Covered by symbols
76-
".data",
77-
".data.rel.ro",
78-
".rodata",
79-
".text",
80-
81-
// Does not contribute to file size
82-
".bss",
83-
".tbss",
84-
85-
// Debug info / stripped
86-
".debug_abbrev",
87-
".debug_aranges",
88-
".debug_info",
89-
".debug_line",
90-
".debug_line_str",
91-
".debug_loc",
92-
".debug_loclists",
93-
".debug_macro",
94-
".debug_ranges",
95-
".debug_rnglists",
96-
".debug_str",
97-
".strtab",
98-
".symtab",
99-
];
100-
10174
var cwd = Directory.current.path;
10275
String prettyPath(String path) {
10376
if (path.startsWith(cwd)) {
@@ -110,31 +83,28 @@ String prettyPath(String path) {
11083
}
11184

11285
main(List<String> args) {
113-
if (args.isEmpty) {
114-
print("Usage: binary_size <binaries>");
86+
if (args.length != 2) {
87+
print("Usage: binary_size <stripped> <unstripped>");
11588
exit(1);
11689
}
11790

118-
for (var arg in args) {
119-
analyze(arg);
120-
}
121-
}
122-
123-
analyze(String binaryPath) {
124-
var nmExec = "nm";
125-
var nmArgs = ["-a", "--demangle", "--line-numbers",
126-
"--print-size", binaryPath];
127-
var nmResult = Process.runSync(nmExec, nmArgs);
128-
if (nmResult.exitCode != 0) {
129-
print("+ ${nmExec} ${nmArgs.join(' ')}");
130-
print(nmResult.exitCode);
131-
print(nmResult.stdout);
132-
print(nmResult.stderr);
91+
var strippedPath = args[0];
92+
var unstrippedPath = args[1];
93+
94+
var bloatyExec = "bloaty";
95+
var bloatyArgs = ["-d", "symbols,compileunits", "--domain=file", "-n", "0",
96+
"--csv", "--debug-file", unstrippedPath, strippedPath];
97+
var bloatyResult = Process.runSync(bloatyExec, bloatyArgs);
98+
if (bloatyResult.exitCode != 0) {
99+
print("+ ${bloatyExec} ${bloatyArgs.join(' ')}");
100+
print(bloatyResult.exitCode);
101+
print(bloatyResult.stdout);
102+
print(bloatyResult.stderr);
133103
exit(1);
134104
}
135105

136106
var root = new Symbol();
137-
root.name = binaryPath;
107+
root.name = strippedPath;
138108
root.type = "path";
139109
root.shallowSize = 0;
140110
var paths = new Map<String, Symbol>();
@@ -159,100 +129,44 @@ analyze(String binaryPath) {
159129
p.children.add(s);
160130
}
161131

162-
var lines = nmResult.stdout.split("\n");
163-
var regex = new RegExp("([0-9a-f]+) ([0-9a-f]+) ([a-zA-z]) (.*)");
132+
var lines = bloatyResult.stdout.split("\n");
133+
var header = true;
164134
for (var line in lines) {
165-
print(line);
166-
var match = regex.firstMatch(line);
167-
if (match == null) {
135+
if (header) {
136+
header = false;
168137
continue;
169138
}
170-
171-
var address = int.parse(match[1]!, radix: 16);
172-
var size = int.parse(match[2]!, radix: 16);
173-
var type = match[3];
174-
if (type == "b" || type == "B") {
175-
// Uninitialized data does not contribute to file size.
139+
if (line.isEmpty) {
176140
continue;
177141
}
178142

179-
var nameAndPath = match[4]!.split("\t");
180-
var name = nameAndPath[0].trim();
181-
var path = nameAndPath.length == 1 ? "" : nameAndPath[1].trim();
182-
var colon = path.lastIndexOf(":");
183-
if (colon > 0) {
184-
path = path.substring(0, colon);
185-
}
186-
path = prettyPath(path);
143+
var columns = line.split(",");
144+
var name = columns[0];
145+
var path = columns[1];
146+
var vmSize = int.parse(columns[2]);
147+
var fileSize = int.parse(columns[3]);
187148

188-
for (var prefix in const ["vtable for ",
189-
"typeinfo for ",
190-
"typeinfo name for "]) {
191-
if (name.startsWith(prefix)) {
192-
name = name.substring(prefix.length);
193-
path = prefix;
194-
}
195-
}
149+
path = prettyPath(path);
196150

197151
var s = new Symbol();
198152
s.name = name;
199-
s.type = type;
200-
s.shallowSize = size;
153+
s.type = "symbol";
154+
s.shallowSize = fileSize;
201155
addToPath(s, path);
202156
}
203157

204-
var readExec = "readelf";
205-
var readArgs = ["--sections", binaryPath];
206-
var readResult = Process.runSync(readExec, readArgs);
207-
if (readResult.exitCode != 0) {
208-
print("+ ${readExec} ${readArgs.join(' ')}");
209-
print(readResult.exitCode);
210-
print(readResult.stdout);
211-
print(readResult.stderr);
212-
exit(1);
213-
}
214-
215-
lines = readResult.stdout.split("\n");
216-
var nameRegex = new RegExp("\\[([ 0-9a-f]+)\\] ([_0-9a-zA-Z.]+)");
217-
var sizeRegex = new RegExp("([_0-9a-f]+)");
218-
var sectionName = null;
219-
for (var line in lines) {
220-
print(line);
221-
var match = nameRegex.firstMatch(line);
222-
if (match != null) {
223-
sectionName = match[2];
224-
continue;
225-
}
226-
match = sizeRegex.firstMatch(line);
227-
if (match != null) {
228-
int size = int.parse(match[1]!, radix: 16);
229-
230-
if (sectionName != null && !filteredSections.contains(sectionName)) {
231-
var s = new Symbol();
232-
s.name = sectionName;
233-
s.type = "section";
234-
s.shallowSize = size;
235-
addToPath(s, "");
236-
}
237-
238-
sectionName = null;
239-
continue;
240-
}
241-
sectionName = null;
242-
}
243-
244158
root.compressTrivialPaths();
245159
root.computeRetainedSize();
246160

247161
var json = new StringBuffer();
248162
root.writeJson(json);
249163

250164
var html = viewer.replaceAll("__DATA__", json.toString());
251-
new File("${binaryPath}.html").writeAsStringSync(html);
165+
new File("${strippedPath}.html").writeAsStringSync(html);
252166

253167
// This written as a URL instead of path because some terminals will
254168
// automatically recognize it and make it a link.
255-
var url = Directory.current.uri.resolve("${binaryPath}.html");
169+
var url = Directory.current.uri.resolve("${strippedPath}.html");
256170
print("Wrote $url");
257171
}
258172

0 commit comments

Comments
 (0)