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' | 7 import 'dart:convert' |
8 show HtmlEscape, JsonEncoder, StringConversionSink, ChunkedConversionSink; | 8 show HtmlEscape, JsonEncoder, StringConversionSink, ChunkedConversionSink; |
9 | 9 |
10 import 'package:dart2js_info/info.dart'; | 10 import 'package:dart2js_info/info.dart'; |
(...skipping 13 matching lines...) Expand all Loading... |
24 TypeMask; | 24 TypeMask; |
25 import 'deferred_load.dart' show | 25 import 'deferred_load.dart' show |
26 OutputUnit; | 26 OutputUnit; |
27 import 'js_backend/js_backend.dart' show | 27 import 'js_backend/js_backend.dart' show |
28 JavaScriptBackend; | 28 JavaScriptBackend; |
29 import 'js_emitter/full_emitter/emitter.dart' as full show | 29 import 'js_emitter/full_emitter/emitter.dart' as full show |
30 Emitter; | 30 Emitter; |
31 import 'js/js.dart' as jsAst; | 31 import 'js/js.dart' as jsAst; |
32 import 'universe/universe.dart' show | 32 import 'universe/universe.dart' show |
33 UniverseSelector; | 33 UniverseSelector; |
| 34 import 'stats/builder.dart'; |
34 | 35 |
35 class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> { | 36 class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> { |
36 final Compiler compiler; | 37 final Compiler compiler; |
37 | 38 |
38 final AllInfo result = new AllInfo(); | 39 final AllInfo result = new AllInfo(); |
39 final Map<Element, Info> _elementToInfo = <Element, Info>{}; | 40 final Map<Element, Info> _elementToInfo = <Element, Info>{}; |
40 final Map<ConstantValue, Info> _constantToInfo = <ConstantValue, Info>{}; | 41 final Map<ConstantValue, Info> _constantToInfo = <ConstantValue, Info>{}; |
41 final Map<OutputUnit, OutputUnitInfo> _outputToInfo = {}; | 42 final Map<OutputUnit, OutputUnitInfo> _outputToInfo = {}; |
42 | 43 |
43 ElementInfoCollector(this.compiler); | 44 ElementInfoCollector(this.compiler); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 classInfo.fields.isEmpty && | 220 classInfo.fields.isEmpty && |
220 classInfo.functions.isEmpty) { | 221 classInfo.functions.isEmpty) { |
221 return null; | 222 return null; |
222 } | 223 } |
223 result.classes.add(classInfo); | 224 result.classes.add(classInfo); |
224 return classInfo; | 225 return classInfo; |
225 } | 226 } |
226 | 227 |
227 FunctionInfo visitFunctionElement(FunctionElement element, _) { | 228 FunctionInfo visitFunctionElement(FunctionElement element, _) { |
228 int size = compiler.dumpInfoTask.sizeOf(element); | 229 int size = compiler.dumpInfoTask.sizeOf(element); |
| 230 // TODO(sigmund): consider adding a small info to represent unreachable |
| 231 // code here. |
229 if (size == 0 && !shouldKeep(element)) return null; | 232 if (size == 0 && !shouldKeep(element)) return null; |
230 | 233 |
231 String name = element.name; | 234 String name = element.name; |
232 int kind = FunctionInfo.TOP_LEVEL_FUNCTION_KIND; | 235 int kind = FunctionInfo.TOP_LEVEL_FUNCTION_KIND; |
233 var enclosingElement = element.enclosingElement; | 236 var enclosingElement = element.enclosingElement; |
234 if (enclosingElement.isField || | 237 if (enclosingElement.isField || |
235 enclosingElement.isFunction || | 238 enclosingElement.isFunction || |
236 element.isClosure || | 239 element.isClosure || |
237 enclosingElement.isConstructor) { | 240 enclosingElement.isConstructor) { |
238 kind = FunctionInfo.CLOSURE_FUNCTION_KIND; | 241 kind = FunctionInfo.CLOSURE_FUNCTION_KIND; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 child.name = "${parent.name}.${child.name}"; | 313 child.name = "${parent.name}.${child.name}"; |
311 } | 314 } |
312 nestedClosures.add(child); | 315 nestedClosures.add(child); |
313 child.parent = parent; | 316 child.parent = parent; |
314 size += child.size; | 317 size += child.size; |
315 } | 318 } |
316 } | 319 } |
317 } | 320 } |
318 info.closures = nestedClosures; | 321 info.closures = nestedClosures; |
319 result.functions.add(info); | 322 result.functions.add(info); |
| 323 if (const bool.fromEnvironment('send_stats')) { |
| 324 info.measurements = collectSendMeasurements(element, compiler); |
| 325 } |
320 return info; | 326 return info; |
321 } | 327 } |
322 | 328 |
323 OutputUnitInfo _unitInfoForElement(Element element) { | 329 OutputUnitInfo _unitInfoForElement(Element element) { |
324 OutputUnit outputUnit = | 330 OutputUnit outputUnit = |
325 compiler.deferredLoadTask.outputUnitForElement(element); | 331 compiler.deferredLoadTask.outputUnitForElement(element); |
326 return _outputToInfo.putIfAbsent(outputUnit, () { | 332 return _outputToInfo.putIfAbsent(outputUnit, () { |
327 // Dump-info currently only works with the full emitter. If another | 333 // Dump-info currently only works with the full emitter. If another |
328 // emitter is used it will fail here. | 334 // emitter is used it will fail here. |
329 JavaScriptBackend backend = compiler.backend; | 335 JavaScriptBackend backend = compiler.backend; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 List<jsAst.Node> code = _elementToNodes[element]; | 485 List<jsAst.Node> code = _elementToNodes[element]; |
480 if (code == null) return null; | 486 if (code == null) return null; |
481 // Concatenate rendered ASTs. | 487 // Concatenate rendered ASTs. |
482 StringBuffer sb = new StringBuffer(); | 488 StringBuffer sb = new StringBuffer(); |
483 for (jsAst.Node ast in code) { | 489 for (jsAst.Node ast in code) { |
484 sb.writeln(jsAst.prettyPrint(ast, compiler).getText()); | 490 sb.writeln(jsAst.prettyPrint(ast, compiler).getText()); |
485 } | 491 } |
486 return sb.toString(); | 492 return sb.toString(); |
487 } | 493 } |
488 | 494 |
489 void collectInfo() { | |
490 infoCollector = new ElementInfoCollector(compiler)..run(); | |
491 } | |
492 | |
493 void dumpInfo() { | 495 void dumpInfo() { |
494 measure(() { | 496 measure(() { |
495 if (infoCollector == null) { | 497 infoCollector = new ElementInfoCollector(compiler)..run(); |
496 collectInfo(); | |
497 } | |
498 | |
499 StringBuffer jsonBuffer = new StringBuffer(); | 498 StringBuffer jsonBuffer = new StringBuffer(); |
500 dumpInfoJson(jsonBuffer); | 499 dumpInfoJson(jsonBuffer); |
501 compiler.outputProvider('', 'info.json') | 500 compiler.outputProvider('', 'info.json') |
502 ..add(jsonBuffer.toString()) | 501 ..add(jsonBuffer.toString()) |
503 ..close(); | 502 ..close(); |
504 }); | 503 }); |
505 } | 504 } |
506 | 505 |
507 void dumpInfoJson(StringSink buffer) { | 506 void dumpInfoJson(StringSink buffer) { |
508 JsonEncoder encoder = const JsonEncoder.withIndent(' '); | 507 JsonEncoder encoder = const JsonEncoder.withIndent(' '); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 | 559 |
561 ChunkedConversionSink<Object> sink = encoder.startChunkedConversion( | 560 ChunkedConversionSink<Object> sink = encoder.startChunkedConversion( |
562 new StringConversionSink.fromStringSink(buffer)); | 561 new StringConversionSink.fromStringSink(buffer)); |
563 sink.add(result.toJson()); | 562 sink.add(result.toJson()); |
564 compiler.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, { | 563 compiler.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, { |
565 'text': "View the dumped .info.json file at " | 564 'text': "View the dumped .info.json file at " |
566 "https://dart-lang.github.io/dump-info-visualizer" | 565 "https://dart-lang.github.io/dump-info-visualizer" |
567 }); | 566 }); |
568 } | 567 } |
569 } | 568 } |
OLD | NEW |