Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dump_info; | 5 library dump_info; |
| 6 | 6 |
| 7 import 'dart:convert' show HtmlEscape; | 7 import 'dart:convert' show HtmlEscape, JSON; |
| 8 | 8 |
| 9 import 'elements/elements.dart'; | 9 import 'elements/elements.dart'; |
| 10 import 'elements/visitor.dart'; | 10 import 'elements/visitor.dart'; |
| 11 import 'dart2jslib.dart' show | 11 import 'dart2jslib.dart' show |
| 12 Compiler, | 12 Compiler, |
| 13 CompilerTask, | 13 CompilerTask, |
| 14 CodeBuffer; | 14 CodeBuffer; |
| 15 import 'dart_types.dart' show DartType; | 15 import 'dart_types.dart' show DartType; |
| 16 import 'types/types.dart' show TypeMask; | 16 import 'types/types.dart' show TypeMask; |
| 17 import 'util/util.dart' show modifiersToString; | 17 import 'util/util.dart' show modifiersToString; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 } | 80 } |
| 81 | 81 |
| 82 /// An [InfoNode] holds information about a part the program. | 82 /// An [InfoNode] holds information about a part the program. |
| 83 abstract class InfoNode { | 83 abstract class InfoNode { |
| 84 String get name; | 84 String get name; |
| 85 | 85 |
| 86 int get size; | 86 int get size; |
| 87 | 87 |
| 88 void emitHtml(ProgramInfo programInfo, StringSink buffer, | 88 void emitHtml(ProgramInfo programInfo, StringSink buffer, |
| 89 [String indentation = '']); | 89 [String indentation = '']); |
| 90 | |
| 91 Map<String, dynamic> toJson(ProgramInfo programInfo); | |
| 90 } | 92 } |
| 91 | 93 |
| 92 /// An [ElementNode] holds information about an [Element] | 94 /// An [ElementNode] holds information about an [Element] |
| 93 class ElementInfoNode implements InfoNode { | 95 class ElementInfoNode implements InfoNode { |
| 94 /// The name of the represented [Element]. | 96 /// The name of the represented [Element]. |
| 95 final String name; | 97 final String name; |
| 96 | 98 |
| 97 /// The kind of the [Element] represented. This is presented to the | 99 /// The kind of the [Element] represented. This is presented to the |
| 98 /// user, so it might be more specific than [element.kind]. | 100 /// user, so it might be more specific than [element.kind]. |
| 99 final String kind; | 101 final String kind; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 123 | 125 |
| 124 ElementInfoNode({this.name: "", | 126 ElementInfoNode({this.name: "", |
| 125 this.kind: "", | 127 this.kind: "", |
| 126 this.type, | 128 this.type, |
| 127 this.modifiers: "", | 129 this.modifiers: "", |
| 128 this.size, | 130 this.size, |
| 129 this.contents, | 131 this.contents, |
| 130 this.extra: "", | 132 this.extra: "", |
| 131 this.outputUnitId}); | 133 this.outputUnitId}); |
| 132 | 134 |
| 135 Map<String, dynamic> toJson(ProgramInfo programInfo) { | |
| 136 Map<String, dynamic> props = {}; | |
| 137 props['kind'] = this.kind; | |
| 138 props['modifiers'] = this.modifiers; | |
| 139 props['name'] = this.name; | |
| 140 props['type'] = this.type; | |
| 141 props['size'] = this.size; | |
| 142 if (this.size != null) { | |
| 143 props['size_percent'] = | |
| 144 (100 * this.size / programInfo.size).toStringAsFixed(3) + "%"; | |
| 145 } | |
| 146 props['extra'] = this.extra; | |
| 147 if (this.contents != null) { | |
| 148 props['children'] = this.contents.map((c) => c.toJson(programInfo)).toList (); | |
|
Ty Overby
2014/06/20 19:36:47
Line over 80 chars.
Ty Overby
2014/06/20 19:47:28
Done.
| |
| 149 } | |
| 150 return props; | |
| 151 } | |
| 152 | |
| 133 void emitHtml(ProgramInfo programInfo, StringSink buffer, | 153 void emitHtml(ProgramInfo programInfo, StringSink buffer, |
| 134 [String indentation = '']) { | 154 [String indentation = '']) { |
| 135 String kindString = span(esc(kind), cls: 'kind'); | 155 String kindString = span(esc(kind), cls: 'kind'); |
| 136 String modifiersString = span(esc(modifiers), cls: "modifiers"); | 156 String modifiersString = span(esc(modifiers), cls: "modifiers"); |
| 137 | 157 |
| 138 String nameString = span(esc(name), cls: 'name'); | 158 String nameString = span(esc(name), cls: 'name'); |
| 139 String typeString = type == null | 159 String typeString = type == null |
| 140 ? '' | 160 ? '' |
| 141 : span('/* ' + esc(type) + ' */', cls: 'type'); | 161 : span('/* ' + esc(type) + ' */', cls: 'type'); |
| 142 String extraString = span(esc(extra), cls: 'type'); | 162 String extraString = span(esc(extra), cls: 'type'); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 | 210 |
| 191 void emitHtml(ProgramInfo programInfo, StringBuffer buffer, | 211 void emitHtml(ProgramInfo programInfo, StringBuffer buffer, |
| 192 [String indentation = '']) { | 212 [String indentation = '']) { |
| 193 buffer.write(indentation); | 213 buffer.write(indentation); |
| 194 buffer.write(div(description + ' ' + | 214 buffer.write(div(description + ' ' + |
| 195 sizeDescription(generatedCode.length, programInfo), | 215 sizeDescription(generatedCode.length, programInfo), |
| 196 cls: 'kind') + | 216 cls: 'kind') + |
| 197 code(esc(generatedCode))); | 217 code(esc(generatedCode))); |
| 198 buffer.write('\n'); | 218 buffer.write('\n'); |
| 199 } | 219 } |
| 220 | |
| 221 Map<String, dynamic> toJson(ProgramInfo programInfo) { | |
| 222 Map<String, dynamic> props = {}; | |
|
sra1
2014/06/20 19:49:27
You can use the literal syntax to add the always-i
Ty Overby
2014/06/20 19:59:13
Done.
| |
| 223 props['kind'] = 'code'; | |
| 224 props['description'] = description; | |
| 225 props['code'] = generatedCode; | |
| 226 props['size'] = generatedCode.length; | |
| 227 props['sizePercent'] = | |
| 228 (100 * generatedCode.length / programInfo.size).toStringAsFixed(3) + "%"; | |
| 229 | |
| 230 return props; | |
| 231 } | |
| 200 } | 232 } |
| 201 | 233 |
| 202 /// Instances represent information inferred about the program such as | 234 /// Instances represent information inferred about the program such as |
| 203 /// inferred type information or inferred side effects. | 235 /// inferred type information or inferred side effects. |
| 204 class InferredInfoNode implements InfoNode { | 236 class InferredInfoNode implements InfoNode { |
| 205 /// Text describing the represented information. | 237 /// Text describing the represented information. |
| 206 final String description; | 238 final String description; |
| 207 | 239 |
| 208 /// The name of the entity this information is inferred about (for example the | 240 /// The name of the entity this information is inferred about (for example the |
| 209 /// name of a parameter). | 241 /// name of a parameter). |
| 210 final String name; | 242 final String name; |
| 211 | 243 |
| 212 /// The inferred type/side effect. | 244 /// The inferred type/side effect. |
| 213 final String type; | 245 final String type; |
| 214 | 246 |
| 215 get size => 0; | 247 get size => 0; |
| 216 | 248 |
| 217 InferredInfoNode({this.name: "", this.description, this.type}); | 249 InferredInfoNode({this.name: "", this.description, this.type}); |
| 218 | 250 |
| 251 Map<String, dynamic> toJson(ProgramInfo programInfo) { | |
| 252 Map<String, dynamic> props = {}; | |
| 253 props['kind'] = "inferred"; | |
| 254 props['name'] = name; | |
| 255 props['type'] = type; | |
| 256 props['desc'] = description; | |
| 257 return props; | |
| 258 } | |
| 259 | |
| 219 void emitHtml(ProgramInfo programInfo, StringBuffer buffer, | 260 void emitHtml(ProgramInfo programInfo, StringBuffer buffer, |
| 220 [String indentation = '']) { | 261 [String indentation = '']) { |
| 221 buffer.write(indentation); | 262 buffer.write(indentation); |
| 222 buffer.write( | 263 buffer.write( |
| 223 div('${span("Inferred " + description, cls: "kind")} ' | 264 div('${span("Inferred " + description, cls: "kind")} ' |
| 224 '${span(esc(name), cls: "name")} ' | 265 '${span(esc(name), cls: "name")} ' |
| 225 '${span(esc(type), cls: "type")} ', | 266 '${span(esc(type), cls: "type")} ', |
| 226 cls: "attr")); | 267 cls: "attr")); |
| 227 buffer.write('\n'); | 268 buffer.write('\n'); |
| 228 } | 269 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 246 final String dart2jsVersion; | 287 final String dart2jsVersion; |
| 247 | 288 |
| 248 final Map<OutputUnit, int> outputUnitNumbering; | 289 final Map<OutputUnit, int> outputUnitNumbering; |
| 249 | 290 |
| 250 ProgramInfo({this.libraries, | 291 ProgramInfo({this.libraries, |
| 251 this.size, | 292 this.size, |
| 252 this.compilationMoment, | 293 this.compilationMoment, |
| 253 this.compilationDuration, | 294 this.compilationDuration, |
| 254 this.dart2jsVersion, | 295 this.dart2jsVersion, |
| 255 this.outputUnitNumbering: null}); | 296 this.outputUnitNumbering: null}); |
| 297 | |
| 298 Map<String, dynamic> toJson() { | |
| 299 Map<String, dynamic> json = {}; | |
|
Ty Overby
2014/06/20 19:36:47
Either have this variable be called `props` or hav
Ty Overby
2014/06/20 19:47:28
Done.
sra1
2014/06/20 19:49:27
I think `json`.
Ty Overby
2014/06/20 19:59:13
`json` is what I went with.
| |
| 300 json['program_size'] = size; | |
| 301 json['compile_time'] = compilationMoment.toString(); | |
| 302 json['compile_duration'] = compilationDuration.toString(); | |
| 303 json['dart2js_version'] = dart2jsVersion; | |
| 304 return json; | |
| 305 } | |
| 256 } | 306 } |
| 257 | 307 |
| 258 class InfoDumpVisitor extends ElementVisitor<InfoNode> { | 308 class InfoDumpVisitor extends ElementVisitor<InfoNode> { |
| 259 final Compiler compiler; | 309 final Compiler compiler; |
| 260 | 310 |
| 261 /// Contains the elements visited on the path from the library to here. | 311 /// Contains the elements visited on the path from the library to here. |
| 262 final List<Element> stack = new List<Element>(); | 312 final List<Element> stack = new List<Element>(); |
| 263 | 313 |
| 264 final Map<OutputUnit, int> outputUnitNumbering = new Map<OutputUnit, int>(); | 314 final Map<OutputUnit, int> outputUnitNumbering = new Map<OutputUnit, int>(); |
| 265 | 315 |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 525 CodeBuffer codeOf(Element element) { | 575 CodeBuffer codeOf(Element element) { |
| 526 jsAst.Expression code = _generatedCode[element]; | 576 jsAst.Expression code = _generatedCode[element]; |
| 527 return code != null | 577 return code != null |
| 528 ? jsAst.prettyPrint(code, compiler) | 578 ? jsAst.prettyPrint(code, compiler) |
| 529 : compiler.backend.codeOf(element); | 579 : compiler.backend.codeOf(element); |
| 530 } | 580 } |
| 531 | 581 |
| 532 void dumpInfo() { | 582 void dumpInfo() { |
| 533 measure(() { | 583 measure(() { |
| 534 ProgramInfo info = infoDumpVisitor.collectDumpInfo(); | 584 ProgramInfo info = infoDumpVisitor.collectDumpInfo(); |
| 535 StringBuffer buffer = new StringBuffer(); | 585 |
| 536 dumpInfoHtml(info, buffer); | 586 StringBuffer htmlBuffer = new StringBuffer(); |
| 587 dumpInfoHtml(info, htmlBuffer); | |
| 537 compiler.outputProvider('', 'info.html') | 588 compiler.outputProvider('', 'info.html') |
| 538 ..add(buffer.toString()) | 589 ..add(htmlBuffer.toString()) |
| 590 ..close(); | |
| 591 | |
| 592 StringBuffer jsonBuffer = new StringBuffer(); | |
| 593 dumpInfoJson(info, jsonBuffer); | |
| 594 compiler.outputProvider('', 'info.json') | |
| 595 ..add(jsonBuffer.toString()) | |
| 539 ..close(); | 596 ..close(); |
| 540 }); | 597 }); |
| 541 } | 598 } |
| 542 | 599 |
| 600 void dumpInfoJson(ProgramInfo info, StringSink buffer) { | |
| 601 Map entire = {}; | |
| 602 entire['program'] = info.toJson(); | |
| 603 entire['libs'] = info.libraries.map((lib) => lib.toJson(info)).toList(); | |
| 604 buffer.writeln(JSON.encode(entire)); | |
|
Ty Overby
2014/06/20 19:36:47
The performance of this could probably be improved
Ty Overby
2014/06/20 19:47:28
Done.
Ty Overby
2014/06/20 19:47:28
Done.
| |
| 605 } | |
| 606 | |
| 543 void dumpInfoHtml(ProgramInfo info, StringSink buffer) { | 607 void dumpInfoHtml(ProgramInfo info, StringSink buffer) { |
| 544 int totalSize = info.size; | 608 int totalSize = info.size; |
| 545 | 609 |
| 546 buffer.writeln(""" | 610 buffer.writeln(""" |
| 547 <html> | 611 <html> |
| 548 <head> | 612 <head> |
| 549 <title>Dart2JS compilation information</title> | 613 <title>Dart2JS compilation information</title> |
| 550 <style> | 614 <style> |
| 551 code {margin-left: 20px; display: block; white-space: pre; } | 615 code {margin-left: 20px; display: block; white-space: pre; } |
| 552 div.container, div.contained, div.element, div.attr { | 616 div.container, div.contained, div.element, div.attr { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 678 } | 742 } |
| 679 document.querySelector('.sort_by_size').addEventListener('click', | 743 document.querySelector('.sort_by_size').addEventListener('click', |
| 680 function() { | 744 function() { |
| 681 sortBySize(); | 745 sortBySize(); |
| 682 }, false); | 746 }, false); |
| 683 </script> | 747 </script> |
| 684 </body> | 748 </body> |
| 685 </html>"""); | 749 </html>"""); |
| 686 } | 750 } |
| 687 } | 751 } |
| OLD | NEW |