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, JsonEncoder, StringConversionSink; |
| 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); | |
|
floitsch
2014/06/20 22:27:57
I would prefer not to pollute the InfoNode with a
| |
| 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> json = <String, dynamic>{ | |
| 137 'kind': this.kind, | |
| 138 'modifiers': this.modifiers, | |
| 139 'name': this.name, | |
| 140 'type': this.type, | |
| 141 'size': this.size, | |
| 142 'extra': this.extra | |
| 143 }; | |
| 144 | |
| 145 if (this.size != null) { | |
| 146 json['size_percent'] = | |
|
sra1
2014/06/20 22:16:34
inconstistent name - use 'sizePercent' to match on
Ty Overby
2014/06/20 22:58:04
Done.
| |
| 147 (100 * this.size / programInfo.size).toStringAsFixed(3) + "%"; | |
| 148 } | |
| 149 | |
| 150 if (this.contents != null) { | |
| 151 json['children'] = | |
| 152 this.contents.map((c) => c.toJson(programInfo)).toList(); | |
| 153 } | |
| 154 return json; | |
| 155 } | |
| 156 | |
| 133 void emitHtml(ProgramInfo programInfo, StringSink buffer, | 157 void emitHtml(ProgramInfo programInfo, StringSink buffer, |
| 134 [String indentation = '']) { | 158 [String indentation = '']) { |
| 135 String kindString = span(esc(kind), cls: 'kind'); | 159 String kindString = span(esc(kind), cls: 'kind'); |
| 136 String modifiersString = span(esc(modifiers), cls: "modifiers"); | 160 String modifiersString = span(esc(modifiers), cls: "modifiers"); |
| 137 | 161 |
| 138 String nameString = span(esc(name), cls: 'name'); | 162 String nameString = span(esc(name), cls: 'name'); |
| 139 String typeString = type == null | 163 String typeString = type == null |
| 140 ? '' | 164 ? '' |
| 141 : span('/* ' + esc(type) + ' */', cls: 'type'); | 165 : span('/* ' + esc(type) + ' */', cls: 'type'); |
| 142 String extraString = span(esc(extra), cls: 'type'); | 166 String extraString = span(esc(extra), cls: 'type'); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 | 214 |
| 191 void emitHtml(ProgramInfo programInfo, StringBuffer buffer, | 215 void emitHtml(ProgramInfo programInfo, StringBuffer buffer, |
| 192 [String indentation = '']) { | 216 [String indentation = '']) { |
| 193 buffer.write(indentation); | 217 buffer.write(indentation); |
| 194 buffer.write(div(description + ' ' + | 218 buffer.write(div(description + ' ' + |
| 195 sizeDescription(generatedCode.length, programInfo), | 219 sizeDescription(generatedCode.length, programInfo), |
| 196 cls: 'kind') + | 220 cls: 'kind') + |
| 197 code(esc(generatedCode))); | 221 code(esc(generatedCode))); |
| 198 buffer.write('\n'); | 222 buffer.write('\n'); |
| 199 } | 223 } |
| 224 | |
| 225 Map<String, dynamic> toJson(ProgramInfo programInfo) { | |
| 226 return <String, dynamic>{ | |
| 227 'kind': 'code', | |
| 228 'description': description, | |
| 229 'code': generatedCode, | |
| 230 'size': generatedCode.length, | |
| 231 'sizePercent': (100 * generatedCode.length / programInfo.size).toStringAsF ixed(3) + "%" | |
|
sra1
2014/06/20 22:16:34
Long line (should be <= 80 chars)
Maybe abstract
Ty Overby
2014/06/20 22:58:04
Done.
| |
| 232 }; | |
| 233 } | |
| 200 } | 234 } |
| 201 | 235 |
| 202 /// Instances represent information inferred about the program such as | 236 /// Instances represent information inferred about the program such as |
| 203 /// inferred type information or inferred side effects. | 237 /// inferred type information or inferred side effects. |
| 204 class InferredInfoNode implements InfoNode { | 238 class InferredInfoNode implements InfoNode { |
| 205 /// Text describing the represented information. | 239 /// Text describing the represented information. |
| 206 final String description; | 240 final String description; |
| 207 | 241 |
| 208 /// The name of the entity this information is inferred about (for example the | 242 /// The name of the entity this information is inferred about (for example the |
| 209 /// name of a parameter). | 243 /// name of a parameter). |
| 210 final String name; | 244 final String name; |
| 211 | 245 |
| 212 /// The inferred type/side effect. | 246 /// The inferred type/side effect. |
| 213 final String type; | 247 final String type; |
| 214 | 248 |
| 215 get size => 0; | 249 get size => 0; |
| 216 | 250 |
| 217 InferredInfoNode({this.name: "", this.description, this.type}); | 251 InferredInfoNode({this.name: "", this.description, this.type}); |
| 218 | 252 |
| 253 Map<String, dynamic> toJson(ProgramInfo programInfo) { | |
| 254 return <String, dynamic>{ | |
| 255 'kind': "inferred", | |
|
sra1
2014/06/20 22:16:34
Use single quotes unless there are embedded single
Ty Overby
2014/06/20 22:58:04
Done.
| |
| 256 'name': name, | |
| 257 'type': type, | |
| 258 'desc': description | |
| 259 }; | |
| 260 } | |
| 261 | |
| 219 void emitHtml(ProgramInfo programInfo, StringBuffer buffer, | 262 void emitHtml(ProgramInfo programInfo, StringBuffer buffer, |
| 220 [String indentation = '']) { | 263 [String indentation = '']) { |
| 221 buffer.write(indentation); | 264 buffer.write(indentation); |
| 222 buffer.write( | 265 buffer.write( |
| 223 div('${span("Inferred " + description, cls: "kind")} ' | 266 div('${span("Inferred " + description, cls: "kind")} ' |
| 224 '${span(esc(name), cls: "name")} ' | 267 '${span(esc(name), cls: "name")} ' |
| 225 '${span(esc(type), cls: "type")} ', | 268 '${span(esc(type), cls: "type")} ', |
| 226 cls: "attr")); | 269 cls: "attr")); |
| 227 buffer.write('\n'); | 270 buffer.write('\n'); |
| 228 } | 271 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 246 final String dart2jsVersion; | 289 final String dart2jsVersion; |
| 247 | 290 |
| 248 final Map<OutputUnit, int> outputUnitNumbering; | 291 final Map<OutputUnit, int> outputUnitNumbering; |
| 249 | 292 |
| 250 ProgramInfo({this.libraries, | 293 ProgramInfo({this.libraries, |
| 251 this.size, | 294 this.size, |
| 252 this.compilationMoment, | 295 this.compilationMoment, |
| 253 this.compilationDuration, | 296 this.compilationDuration, |
| 254 this.dart2jsVersion, | 297 this.dart2jsVersion, |
| 255 this.outputUnitNumbering: null}); | 298 this.outputUnitNumbering: null}); |
| 299 | |
| 300 Map<String, dynamic> toJson() { | |
| 301 return <String, dynamic>{ | |
| 302 'program_size': size, | |
| 303 'compile_time': compilationMoment.toString(), | |
| 304 'compile_duration': compilationDuration.toString(), | |
| 305 'dart2js_version': dart2jsVersion | |
| 306 }; | |
| 307 } | |
| 256 } | 308 } |
| 257 | 309 |
| 258 class InfoDumpVisitor extends ElementVisitor<InfoNode> { | 310 class InfoDumpVisitor extends ElementVisitor<InfoNode> { |
| 259 final Compiler compiler; | 311 final Compiler compiler; |
| 260 | 312 |
| 261 /// Contains the elements visited on the path from the library to here. | 313 /// Contains the elements visited on the path from the library to here. |
| 262 final List<Element> stack = new List<Element>(); | 314 final List<Element> stack = new List<Element>(); |
| 263 | 315 |
| 264 final Map<OutputUnit, int> outputUnitNumbering = new Map<OutputUnit, int>(); | 316 final Map<OutputUnit, int> outputUnitNumbering = new Map<OutputUnit, int>(); |
| 265 | 317 |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 525 CodeBuffer codeOf(Element element) { | 577 CodeBuffer codeOf(Element element) { |
| 526 jsAst.Expression code = _generatedCode[element]; | 578 jsAst.Expression code = _generatedCode[element]; |
| 527 return code != null | 579 return code != null |
| 528 ? jsAst.prettyPrint(code, compiler) | 580 ? jsAst.prettyPrint(code, compiler) |
| 529 : compiler.backend.codeOf(element); | 581 : compiler.backend.codeOf(element); |
| 530 } | 582 } |
| 531 | 583 |
| 532 void dumpInfo() { | 584 void dumpInfo() { |
| 533 measure(() { | 585 measure(() { |
| 534 ProgramInfo info = infoDumpVisitor.collectDumpInfo(); | 586 ProgramInfo info = infoDumpVisitor.collectDumpInfo(); |
| 535 StringBuffer buffer = new StringBuffer(); | 587 |
| 536 dumpInfoHtml(info, buffer); | 588 StringBuffer htmlBuffer = new StringBuffer(); |
| 589 dumpInfoHtml(info, htmlBuffer); | |
| 537 compiler.outputProvider('', 'info.html') | 590 compiler.outputProvider('', 'info.html') |
| 538 ..add(buffer.toString()) | 591 ..add(htmlBuffer.toString()) |
| 592 ..close(); | |
| 593 | |
| 594 StringBuffer jsonBuffer = new StringBuffer(); | |
| 595 dumpInfoJson(info, jsonBuffer); | |
| 596 compiler.outputProvider('', 'info.json') | |
| 597 ..add(jsonBuffer.toString()) | |
| 539 ..close(); | 598 ..close(); |
| 540 }); | 599 }); |
| 541 } | 600 } |
| 542 | 601 |
| 602 void dumpInfoJson(ProgramInfo info, StringSink buffer) { | |
| 603 Map entire = {}; | |
|
sra1
2014/06/20 22:16:34
Add types.
Ty Overby
2014/06/20 22:58:04
Done.
| |
| 604 entire['program'] = info.toJson(); | |
|
sra1
2014/06/20 22:16:34
maybe include this in the literal.
Ty Overby
2014/06/20 22:58:04
Done.
| |
| 605 entire['libs'] = info.libraries.map((lib) => lib.toJson(info)).toList(); | |
| 606 | |
| 607 JsonEncoder encoder = const JsonEncoder(); | |
| 608 ChunkedConversionSink<Object> sink = | |
| 609 encoder.startChunkedConversion( | |
| 610 new StringConversionSink.fromStringSink(buffer)); | |
| 611 sink.add(entire); | |
| 612 } | |
| 613 | |
| 543 void dumpInfoHtml(ProgramInfo info, StringSink buffer) { | 614 void dumpInfoHtml(ProgramInfo info, StringSink buffer) { |
| 544 int totalSize = info.size; | 615 int totalSize = info.size; |
| 545 | 616 |
| 546 buffer.writeln(""" | 617 buffer.writeln(""" |
| 547 <html> | 618 <html> |
| 548 <head> | 619 <head> |
| 549 <title>Dart2JS compilation information</title> | 620 <title>Dart2JS compilation information</title> |
| 550 <style> | 621 <style> |
| 551 code {margin-left: 20px; display: block; white-space: pre; } | 622 code {margin-left: 20px; display: block; white-space: pre; } |
| 552 div.container, div.contained, div.element, div.attr { | 623 div.container, div.contained, div.element, div.attr { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 678 } | 749 } |
| 679 document.querySelector('.sort_by_size').addEventListener('click', | 750 document.querySelector('.sort_by_size').addEventListener('click', |
| 680 function() { | 751 function() { |
| 681 sortBySize(); | 752 sortBySize(); |
| 682 }, false); | 753 }, false); |
| 683 </script> | 754 </script> |
| 684 </body> | 755 </body> |
| 685 </html>"""); | 756 </html>"""); |
| 686 } | 757 } |
| 687 } | 758 } |
| OLD | NEW |