| 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 | 7 import 'dart:convert' show |
| 8 HtmlEscape, | 8 HtmlEscape, |
| 9 JsonEncoder, | 9 JsonEncoder, |
| 10 StringConversionSink, | 10 StringConversionSink, |
| 11 ChunkedConversionSink; | 11 ChunkedConversionSink; |
| 12 | 12 |
| 13 import 'elements/elements.dart'; | 13 import 'elements/elements.dart'; |
| 14 import 'elements/visitor.dart'; | 14 import 'elements/visitor.dart'; |
| 15 import 'dart2jslib.dart' show | 15 import 'dart2jslib.dart' show |
| 16 Backend, | 16 Backend, |
| 17 CodeBuffer, | 17 CodeBuffer, |
| 18 Compiler, | 18 Compiler, |
| 19 CompilerTask, | 19 CompilerTask, |
| 20 MessageKind; | 20 MessageKind; |
| 21 import 'types/types.dart' show TypeMask; | 21 import 'types/types.dart' show TypeMask; |
| 22 import 'deferred_load.dart' show OutputUnit; | 22 import 'deferred_load.dart' show OutputUnit; |
| 23 import 'js_backend/js_backend.dart' show JavaScriptBackend; | 23 import 'js_backend/js_backend.dart' show JavaScriptBackend; |
| 24 import 'js/js.dart' as jsAst; | 24 import 'js/js.dart' as jsAst; |
| 25 import 'universe/universe.dart' show Selector, UniverseSelector; | 25 import 'universe/universe.dart' show Selector; |
| 26 import 'util/util.dart' show NO_LOCATION_SPANNABLE; | 26 import 'util/util.dart' show NO_LOCATION_SPANNABLE; |
| 27 | 27 |
| 28 /// Maps objects to an id. Supports lookups in | 28 /// Maps objects to an id. Supports lookups in |
| 29 /// both directions. | 29 /// both directions. |
| 30 class IdMapper<T>{ | 30 class IdMapper<T>{ |
| 31 Map<int, T> _idToElement = {}; | 31 Map<int, T> _idToElement = {}; |
| 32 Map<T, int> _elementToId = {}; | 32 Map<T, int> _elementToId = {}; |
| 33 int _idCounter = 0; | 33 int _idCounter = 0; |
| 34 final String name; | 34 final String name; |
| 35 | 35 |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 'inlinedCount': inlinedCount, | 382 'inlinedCount': inlinedCount, |
| 383 'code': emittedCode == null ? null : '$emittedCode', | 383 'code': emittedCode == null ? null : '$emittedCode', |
| 384 'type': element.type.toString(), | 384 'type': element.type.toString(), |
| 385 'outputUnit': mapper._outputUnit.add(outputUnit) | 385 'outputUnit': mapper._outputUnit.add(outputUnit) |
| 386 }; | 386 }; |
| 387 } | 387 } |
| 388 } | 388 } |
| 389 | 389 |
| 390 class Selection { | 390 class Selection { |
| 391 final Element selectedElement; | 391 final Element selectedElement; |
| 392 final TypeMask mask; | 392 final Selector selector; |
| 393 Selection(this.selectedElement, this.mask); | 393 Selection(this.selectedElement, this.selector); |
| 394 } | 394 } |
| 395 | 395 |
| 396 class DumpInfoTask extends CompilerTask { | 396 class DumpInfoTask extends CompilerTask { |
| 397 DumpInfoTask(Compiler compiler) | 397 DumpInfoTask(Compiler compiler) |
| 398 : super(compiler); | 398 : super(compiler); |
| 399 | 399 |
| 400 String get name => "Dump Info"; | 400 String get name => "Dump Info"; |
| 401 | 401 |
| 402 ElementToJsonVisitor infoCollector; | 402 ElementToJsonVisitor infoCollector; |
| 403 | 403 |
| 404 /// The size of the generated output. | 404 /// The size of the generated output. |
| 405 int _programSize; | 405 int _programSize; |
| 406 | 406 |
| 407 // A set of javascript AST nodes that we care about the size of. | 407 // A set of javascript AST nodes that we care about the size of. |
| 408 // This set is automatically populated when registerElementAst() | 408 // This set is automatically populated when registerElementAst() |
| 409 // is called. | 409 // is called. |
| 410 final Set<jsAst.Node> _tracking = new Set<jsAst.Node>(); | 410 final Set<jsAst.Node> _tracking = new Set<jsAst.Node>(); |
| 411 // A mapping from Dart Elements to Javascript AST Nodes. | 411 // A mapping from Dart Elements to Javascript AST Nodes. |
| 412 final Map<Element, List<jsAst.Node>> _elementToNodes = | 412 final Map<Element, List<jsAst.Node>> _elementToNodes = |
| 413 <Element, List<jsAst.Node>>{}; | 413 <Element, List<jsAst.Node>>{}; |
| 414 // A mapping from Javascript AST Nodes to the size of their | 414 // A mapping from Javascript AST Nodes to the size of their |
| 415 // pretty-printed contents. | 415 // pretty-printed contents. |
| 416 final Map<jsAst.Node, int> _nodeToSize = <jsAst.Node, int>{}; | 416 final Map<jsAst.Node, int> _nodeToSize = <jsAst.Node, int>{}; |
| 417 | 417 |
| 418 final Map<Element, Set<UniverseSelector>> selectorsFromElement = {}; | 418 final Map<Element, Set<Selector>> selectorsFromElement = {}; |
| 419 final Map<Element, int> inlineCount = <Element, int>{}; | 419 final Map<Element, int> inlineCount = <Element, int>{}; |
| 420 // A mapping from an element to a list of elements that are | 420 // A mapping from an element to a list of elements that are |
| 421 // inlined inside of it. | 421 // inlined inside of it. |
| 422 final Map<Element, List<Element>> inlineMap = <Element, List<Element>>{}; | 422 final Map<Element, List<Element>> inlineMap = <Element, List<Element>>{}; |
| 423 | 423 |
| 424 /// Register the size of the generated output. | 424 /// Register the size of the generated output. |
| 425 void reportSize(int programSize) { | 425 void reportSize(int programSize) { |
| 426 _programSize = programSize; | 426 _programSize = programSize; |
| 427 } | 427 } |
| 428 | 428 |
| 429 void registerInlined(Element element, Element inlinedFrom) { | 429 void registerInlined(Element element, Element inlinedFrom) { |
| 430 inlineCount.putIfAbsent(element, () => 0); | 430 inlineCount.putIfAbsent(element, () => 0); |
| 431 inlineCount[element] += 1; | 431 inlineCount[element] += 1; |
| 432 inlineMap.putIfAbsent(inlinedFrom, () => new List<Element>()); | 432 inlineMap.putIfAbsent(inlinedFrom, () => new List<Element>()); |
| 433 inlineMap[inlinedFrom].add(element); | 433 inlineMap[inlinedFrom].add(element); |
| 434 } | 434 } |
| 435 | 435 |
| 436 /** | 436 /** |
| 437 * Registers that a function uses a selector in the | 437 * Registers that a function uses a selector in the |
| 438 * function body | 438 * function body |
| 439 */ | 439 */ |
| 440 void elementUsesSelector(Element element, UniverseSelector selector) { | 440 void elementUsesSelector(Element element, Selector selector) { |
| 441 if (compiler.dumpInfo) { | 441 if (compiler.dumpInfo) { |
| 442 selectorsFromElement | 442 selectorsFromElement |
| 443 .putIfAbsent(element, () => new Set<UniverseSelector>()) | 443 .putIfAbsent(element, () => new Set<Selector>()) |
| 444 .add(selector); | 444 .add(selector); |
| 445 } | 445 } |
| 446 } | 446 } |
| 447 | 447 |
| 448 /** | 448 /** |
| 449 * Returns an iterable of [Selection]s that are used by | 449 * Returns an iterable of [Selection]s that are used by |
| 450 * [element]. Each [Selection] contains an element that is | 450 * [element]. Each [Selection] contains an element that is |
| 451 * used and the selector that selected the element. | 451 * used and the selector that selected the element. |
| 452 */ | 452 */ |
| 453 Iterable<Selection> getRetaining(Element element) { | 453 Iterable<Selection> getRetaining(Element element) { |
| 454 if (!selectorsFromElement.containsKey(element)) { | 454 if (!selectorsFromElement.containsKey(element)) { |
| 455 return const <Selection>[]; | 455 return const <Selection>[]; |
| 456 } else { | 456 } else { |
| 457 return selectorsFromElement[element].expand( | 457 return selectorsFromElement[element].expand( |
| 458 (UniverseSelector selector) { | 458 (selector) { |
| 459 return compiler.world.allFunctions.filter( | 459 return compiler.world.allFunctions.filter(selector).map((element) { |
| 460 selector.selector, selector.mask) | 460 return new Selection(element, selector); |
| 461 .map((element) { | |
| 462 return new Selection(element, selector.mask); | |
| 463 }); | 461 }); |
| 464 }); | 462 }); |
| 465 } | 463 } |
| 466 } | 464 } |
| 467 | 465 |
| 468 // Returns true if we care about tracking the size of | 466 // Returns true if we care about tracking the size of |
| 469 // this node. | 467 // this node. |
| 470 bool isTracking(jsAst.Node code) { | 468 bool isTracking(jsAst.Node code) { |
| 471 if (compiler.dumpInfo) { | 469 if (compiler.dumpInfo) { |
| 472 return _tracking.contains(code); | 470 return _tracking.contains(code); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 // Don't bother recording an empty list of dependencies. | 556 // Don't bother recording an empty list of dependencies. |
| 559 if (pulling.length > 0) { | 557 if (pulling.length > 0) { |
| 560 String fnId = infoCollector.idOf(fn); | 558 String fnId = infoCollector.idOf(fn); |
| 561 // Some dart2js builtin functions are not | 559 // Some dart2js builtin functions are not |
| 562 // recorded. Don't register these. | 560 // recorded. Don't register these. |
| 563 if (fnId != null) { | 561 if (fnId != null) { |
| 564 holding[fnId] = pulling | 562 holding[fnId] = pulling |
| 565 .map((selection) { | 563 .map((selection) { |
| 566 return <String, String>{ | 564 return <String, String>{ |
| 567 "id": infoCollector.idOf(selection.selectedElement), | 565 "id": infoCollector.idOf(selection.selectedElement), |
| 568 "mask": selection.mask.toString() | 566 "mask": selection.selector.mask.toString() |
| 569 }; | 567 }; |
| 570 }) | 568 }) |
| 571 // Filter non-null ids for the same reason as above. | 569 // Filter non-null ids for the same reason as above. |
| 572 .where((a) => a['id'] != null) | 570 .where((a) => a['id'] != null) |
| 573 .toList(); | 571 .toList(); |
| 574 } | 572 } |
| 575 } | 573 } |
| 576 } | 574 } |
| 577 | 575 |
| 578 // Track dependencies that come from inlining. | 576 // Track dependencies that come from inlining. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 ChunkedConversionSink<Object> sink = | 632 ChunkedConversionSink<Object> sink = |
| 635 encoder.startChunkedConversion( | 633 encoder.startChunkedConversion( |
| 636 new StringConversionSink.fromStringSink(buffer)); | 634 new StringConversionSink.fromStringSink(buffer)); |
| 637 sink.add(outJson); | 635 sink.add(outJson); |
| 638 compiler.reportInfo(NO_LOCATION_SPANNABLE, | 636 compiler.reportInfo(NO_LOCATION_SPANNABLE, |
| 639 const MessageKind( | 637 const MessageKind( |
| 640 "View the dumped .info.json file at " | 638 "View the dumped .info.json file at " |
| 641 "https://dart-lang.github.io/dump-info-visualizer")); | 639 "https://dart-lang.github.io/dump-info-visualizer")); |
| 642 } | 640 } |
| 643 } | 641 } |
| OLD | NEW |