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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/dump_info.dart

Issue 90713003: Dart2js option to dump info about compilation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library dump_types;
6
7 import 'elements/elements.dart';
8 import 'elements/visitor.dart';
9 import 'dart:convert' show HtmlEscape;
10 import 'dart2jslib.dart'
11 show Compiler,
12 CompilerTask,
13 CodeBuffer;
14 import 'dart_types.dart' show DartType;
15
16 // TODO (sigurdm) A search function.
17 // TODO (sigurdm) Output size of classes.
18 // TODO (sigurdm) Print that we dumped the HTML-file.
19 // TODO (sigurdm) Include why a given element was included in the output.
20 // TODO (sigurdm) Include how much output grew because of mirror support.
21 // TODO (sigurdm) Write each function with parameter names.
22 // TODO (sigurdm) Write how much space the boilerplate takes.
23
24 class CodeSizeCounter {
25 final Map<Element, int> generatedSize = new Map<Element, int>();
26
27 int getGeneratedSizeOf(Element element) {
28 int result = generatedSize[element];
29 return result == null ? 0 : result;
30 }
31
32 void countCode(Element element, int added) {
33 int before = generatedSize.putIfAbsent(element, () => 0);
34 generatedSize[element] = before + added;
35 }
36 }
37
38 class ElementInfo {
39 String name;
kasperl 2013/11/29 12:03:13 Can some of these fields be final?
sigurdm 2013/12/02 14:09:50 all
40 String kind;
41 String type;
42 String modifiers;
43 String generatedCode;
44 // How to present this piece of information
45 // As "element" or "code"
46 String presentation;
47 int size; // How many bytes does this take in the output
48 List<ElementInfo> contents;
49 ElementInfo({String this.name: "",
kasperl 2013/11/29 12:03:13 No need to add the types for the 'this.name' style
sigurdm 2013/12/02 14:09:50 Great!
50 String this.kind: "",
51 String this.type: "",
52 String this.modifiers: "",
53 int this.size,
54 String this.generatedCode,
55 String this.presentation: "element",
56 List<ElementInfo> this.contents});
57 }
58
59 class ProgramInfo {
kasperl 2013/11/29 12:03:13 Use final fields and no types for 'this.name' styl
sigurdm 2013/12/02 14:09:50 Done.
60 String name;
61 String presentation;
62 List<ElementInfo> libraries;
63 int size; // How many bytes is the output
64 DateTime compilationMoment;
65 int compilationDuration;
66 String dart2jsVersion;
67
68 ProgramInfo({String this.name,
69 String this.presentation,
70 List<ElementInfo> this.libraries,
71 int this.size, DateTime this.compilationMoment,
72 int this.compilationDuration, String this.dart2jsVersion});
73 }
74
75 class InfoDumpVisitor extends ElementVisitor<ElementInfo> {
76
77 Compiler compiler;
78
79 InfoDumpVisitor(Compiler this.compiler);
80
81 ElementInfo visitElement(Element element) {
82 compiler.internalError("This element of kind ${element.kind} "
83 "does not support dumping of types",
kasperl 2013/11/29 12:03:13 4 space indent.
sigurdm 2013/12/02 14:09:50 Done.
84 token: element.position());
85 }
86
87 ElementInfo visitLibraryElement(LibraryElement element) {
88 List<ElementInfo> contents = new List<ElementInfo>();
89 int size = compiler.dumpInfoTask.codeSizeCounter
kasperl 2013/11/29 12:03:13 Doesn't this fit on one line?
sigurdm 2013/12/02 14:09:50 No
90 .getGeneratedSizeOf(element);
91 if (size == 0) return null;
92 element.forEachLocalMember((Element member) {
93 ElementInfo info = member.accept(this);
94 if (info != null) {
95 contents.add(info);
96 }
97 });
98
99 String nameString = element.getLibraryName() == "" ?
kasperl 2013/11/29 12:03:13 I suggest breaking before ? and formatting this al
sigurdm 2013/12/02 14:09:50 Done.
100 "<unnamed>" : element.getLibraryName();
101 contents.sort((ElementInfo m1, ElementInfo m2) {
102 return m1.name.compareTo(m2.name);
103 });
104 return new ElementInfo(
105 type: element.canonicalUri.toString(),
kasperl 2013/11/29 12:03:13 4 space indent.
sigurdm 2013/12/02 14:09:50 Done.
106 kind: "library",
107 name: nameString,
108 size: size,
109 modifiers: "",
110 contents: contents);
111 }
112
113 ElementInfo visitTypedefElement(TypedefElement element) {
114 return element.thisType == null ? null :
115 new ElementInfo(
116 type: element.thisType.toString(),
117 kind: "typedef",
118 name: element.name);
119 }
120
121 ElementInfo visitVariableElement(VariableElement element) {
122 DartType type = element.computeType(compiler);
123 if (type == null) return null;
124 String modifiersString = element.modifiers.toString() == "" ?
kasperl 2013/11/29 12:03:13 Consider the alternative ?: formatting with respec
sigurdm 2013/12/02 14:09:50 Done.
125 "" : element.modifiers.toString()+" ";
126 List inferredType = [new ElementInfo(
127 kind: "inferred type",
kasperl 2013/11/29 12:03:13 4 space indent.
sigurdm 2013/12/02 14:09:50 Done.
128 name: "",
129 type: compiler.typesTask.getGuaranteedTypeOfElement(element).toString(),
130 modifiers: "")];
131 return new ElementInfo(
132 kind: "field",
kasperl 2013/11/29 12:03:13 4 space indent.
sigurdm 2013/12/02 14:09:50 Done.
133 type: type.toString(),
134 name: element.name,
135 modifiers: modifiersString,
136 contents: inferredType);
137 }
138
139 ElementInfo visitClassElement(ClassElement element) {
140 String modifiersString = element.modifiers.toString() == "" ?
141 "" : element.modifiers.toString()+" ";
142 if (!element.isResolved) return null;
143 String supersString = element.allSupertypes == null ? "" :
144 "implements ${element.allSupertypes}";
145 List contents = [];
146 element.forEachLocalMember((Element member) {
147 ElementInfo info = member.accept(this);
148 if (info != null) {
149 contents.add(info);
150 }
151 });
152 if (contents.isEmpty) {
153 return null;
154 }
155 contents.sort((ElementInfo m1, ElementInfo m2) {
kasperl 2013/11/29 12:03:13 Why are these called m1 and m2? e1 and e2 seems mo
sigurdm 2013/12/02 14:09:50 Looong story... fixed
156 return m1.name.compareTo(m2.name);
157 });
158 return new ElementInfo(
159 kind: "class",
kasperl 2013/11/29 12:03:13 4 space indent (lots of occurrences).
sigurdm 2013/12/02 14:09:50 On 2013/11/29 12:03:13, kasperl wrote: > 4 space i
160 name: element.name,
161 type: supersString,
162 modifiers: modifiersString,
163 contents: contents);
164 }
165
166 ElementInfo visitFunctionElement(FunctionElement element) {
167 CodeBuffer emittedCode = compiler.backend.codeOf(element);
168 if (emittedCode == null) {
169 return null;
170 }
171 String modifiersString = element.modifiers.toString() == "" ?
172 "" : element.modifiers.toString()+" ";
173 String kindString = "function";
174 String nameString = element.name;
175 if (element.isConstructor()) {
176 nameString = element.name == "" ? "${element.enclosingElement.name}()" :
177 "${element.enclosingElement.name}.${element.name}";
178 kindString = "constructor";
179 }
180 List contents = [];
181 FunctionSignature signature = element.computeSignature(compiler);
182 signature.forEachParameter((parameter) {
183 contents.add(new ElementInfo(
184 kind: "inferred",
185 name: parameter.name,
186 modifiers: "parameter type",
187 type: compiler.typesTask
kasperl 2013/11/29 12:03:13 Maybe the type parameter to the ElementInfo constr
sigurdm 2013/12/02 14:09:50 Hmm - maybe - right now the "type" is some explana
188 .getGuaranteedTypeOfElement(parameter).toString()));
189 });
190 contents.add(new ElementInfo(
191 kind: "inferred",
192 modifiers: "return type",
193 type: compiler.typesTask
194 .getGuaranteedReturnTypeOfElement(element).toString()));
195 contents.add(new ElementInfo(
196 kind: "inferred",
197 modifiers: "side effects",
198 type: compiler.world.getSideEffectsOfElement(element).toString()));
199 contents.add(new ElementInfo(
200 name: "Generated code",
201 presentation: "code",
202 generatedCode: emittedCode.getText()));
203 return new ElementInfo(
204 type: element.type.toString(),
205 kind: kindString,
206 name: nameString,
207 size: emittedCode.length,
208 modifiers: modifiersString,
209 contents: contents);
210 }
211 }
212
213 class DumpInfoTask extends CompilerTask {
214 DumpInfoTask(Compiler compiler) :
215 super(compiler),
216 infoDumpVisitor = new InfoDumpVisitor(compiler);
217
218 String name = "Dump Info";
219
220 final CodeSizeCounter codeSizeCounter = new CodeSizeCounter();
221
222 final InfoDumpVisitor infoDumpVisitor;
223
224 void dumpInfo() {
225 measure(() {
226 ProgramInfo info = collectDumpInfo();
227 StringBuffer buffer = new StringBuffer();
228 dumpInfoHtml(info, buffer);
229 compiler.outputProvider('', 'info.html')
230 ..add(buffer.toString())
kasperl 2013/11/29 12:03:13 4 space indent (match up to the next line).
sigurdm 2013/12/02 14:09:50 Done.
231 ..close();
232 });
233 }
234
235 ProgramInfo collectDumpInfo() {
236 List<LibraryElement> sortedLibraries = compiler.libraries.values.toList();
237 sortedLibraries.sort((LibraryElement l1, LibraryElement l2) {
238 if (l1.isPlatformLibrary && !l2.isPlatformLibrary) {
239 return 1;
240 } else if (!l1.isPlatformLibrary && l2.isPlatformLibrary) {
241 return -1;
242 }
243 return l1.getLibraryName().compareTo(l2.getLibraryName());
244 });
245
246 List<ElementInfo> libraryInfos = new List<ElementInfo>.from(sortedLibraries
kasperl 2013/11/29 12:03:13 Maybe compute the Iterable outside to make that co
sigurdm 2013/12/02 14:09:50 Done.
247 .map((library) => infoDumpVisitor.visit(library))
248 .where((library) => library != null));
249
250 return new ProgramInfo(
251 compilationDuration: compiler.totalCompileTime.elapsedTicks,
kasperl 2013/11/29 12:03:13 Weird indentation. Should be 4 space relative to t
sigurdm 2013/12/02 14:09:50 Done.
252 // TODO (sigurdm) Also count the size of deferred code
253 size: compiler.assembledCode.length,
254 libraries: libraryInfos,
255 compilationMoment: new DateTime.now(),
256 dart2jsVersion: compiler.hasBuildId ? compiler.buildId : null);
257 }
258
259 void dumpInfoHtml(ProgramInfo info, StringSink buffer) {
260 tag(String element) {
261 return (String content, {String cls}) {
262 return '<$element${cls == null ? '' : ' class="$cls"'}>'
kasperl 2013/11/29 12:03:13 I'd compute the (cls == null ? '' : ' class ...')
sigurdm 2013/12/02 14:09:50 Done.
263 '$content</$element>';
264 };
265 }
266 var div = tag('div');
267 var span = tag('span');
268 var code = tag('code');
269 var h2 = tag('h2');
270 int totalSize = info.size;
271 void dumpElement(ElementInfo description) {
272 var esc = const HtmlEscape().convert;
273 if (description.presentation == 'code') {
274 buffer.write(div(description.name, cls: 'kind') +
275 code(esc(description.generatedCode)));
276 } else {
277 String kind = span(esc(description.kind), cls: 'kind');
278 String modifiers = span(esc(description.modifiers), cls: "modifiers");
279 String size = '';
280 if (description.size != null) {
281 size = 'Size: ' +
282 span('${description.size} bytes '
283 '(${description.size * 100 ~/ totalSize})%',
284 cls: "size");
285 }
286 String name = span(esc(description.name), cls: 'name');
287 String type = span(esc(description.type), cls: 'type');
288 String describe = [kind, modifiers, name, size, type].join(' ');
289
290 if (description.contents != null) {
291 buffer.write(div("+$describe", cls: "container"));
292 String contents = "No Members";
293 buffer.write('<div class="contained">');
294 if (description.contents.isEmpty) {
295 buffer.writeln("No members");
296 }
297 for (Object subElementDescription in description.contents) {
298 dumpElement(subElementDescription);
299 }
300 buffer.write("</div>");
301 } else {
302 buffer.writeln(describe);
303 }
304 }
305 }
306 buffer.writeln("""
307 <html>
308 <head>
309 <title>Dart2JS compilation information</title>
310 <style>
311 div.show {display:block;}
312 code {margin-left: 20px; display: block;}
313 div.contained {margin-left: 20px;}
314 div {margin-top:0px;
315 margin-bottom: 0px;
316 white-space: pre; /*border: 1px solid;*/}
317 span.kind {font-weight:bold;}
318 span.modifiers {font-weight:bold;}
319 span.name {font-style:italic}
320 span.type {color:blue;}
321 </style>
322 </head>
323 <body>
324 <h1>Dart2js compilation information</h1>""");
325 buffer.writeln(h2('Compilation took place: '
326 '${info.compilationMoment}'));
327 buffer.writeln(h2('Compilation took: '
328 '${info.compilationDuration/1000000} seconds'));
329 buffer.writeln(h2('Output size: ${info.size} bytes'));
330 if (info.dart2jsVersion != null) {
331 buffer.writeln(h2('Dart2js version: ${info.dart2jsVersion}'));
332 }
333
334 info.libraries.forEach(dumpElement);
335
336 // TODO (sigurdm) this script should be written in dart
kasperl 2013/11/29 12:03:13 Usually we format these TODO comment like this:
sigurdm 2013/12/02 14:09:50 Done.
337 buffer.writeln(r"""
338 <script type="text/javascript">
339 function toggler(element) { return function(e) {
kasperl 2013/11/29 12:03:13 Newline before return and more indentation.
sigurdm 2013/12/02 14:09:50 Done.
340 element.hidden = ! element.hidden;
kasperl 2013/11/29 12:03:13 No space after !.
sigurdm 2013/12/02 14:09:50 Done.
341 console.log(element);
kasperl 2013/11/29 12:03:13 Do you really want to log this to the console? Loo
sigurdm 2013/12/02 14:09:50 Done.
342 }
343 }
344 var containers = document.getElementsByClassName('container');
345 for(var i = 0; i < containers.length; i++) {
kasperl 2013/11/29 12:03:13 for( -> for (
sigurdm 2013/12/02 14:09:50 Done.
346 var container = containers[i];
347 var hidden = 0;
348 container.addEventListener('click',
349 toggler(container.nextElementSibling), false);
350 container.nextElementSibling.hidden=true;
kasperl 2013/11/29 12:03:13 Spaces around =.
sigurdm 2013/12/02 14:09:50 Done.
351 };
352 </script>
353 </body>
354 </html>""");
355 }
356 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698