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 ChunkedConversionSink, JsonEncoder, StringConversionSink; | 8 show ChunkedConversionSink, JsonEncoder, StringConversionSink; |
9 | 9 |
10 import 'package:dart2js_info/info.dart'; | 10 import 'package:dart2js_info/info.dart'; |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 final Map<Element, List<Element>> inlineMap = <Element, List<Element>>{}; | 412 final Map<Element, List<Element>> inlineMap = <Element, List<Element>>{}; |
413 | 413 |
414 final Map<Element, WorldImpact> impacts = <Element, WorldImpact>{}; | 414 final Map<Element, WorldImpact> impacts = <Element, WorldImpact>{}; |
415 | 415 |
416 /// Register the size of the generated output. | 416 /// Register the size of the generated output. |
417 void reportSize(int programSize) { | 417 void reportSize(int programSize) { |
418 _programSize = programSize; | 418 _programSize = programSize; |
419 } | 419 } |
420 | 420 |
421 void reportInlined(Element element, Element inlinedFrom) { | 421 void reportInlined(Element element, Element inlinedFrom) { |
| 422 element = element.declaration; |
| 423 inlinedFrom = inlinedFrom.declaration; |
| 424 |
422 inlineCount.putIfAbsent(element, () => 0); | 425 inlineCount.putIfAbsent(element, () => 0); |
423 inlineCount[element] += 1; | 426 inlineCount[element] += 1; |
424 inlineMap.putIfAbsent(inlinedFrom, () => new List<Element>()); | 427 inlineMap.putIfAbsent(inlinedFrom, () => new List<Element>()); |
425 inlineMap[inlinedFrom].add(element); | 428 inlineMap[inlinedFrom].add(element); |
426 } | 429 } |
427 | 430 |
428 final Map<Element, Set<Element>> _dependencies = {}; | |
429 void registerDependency(Element target) { | |
430 if (compiler.options.dumpInfo) { | |
431 _dependencies | |
432 .putIfAbsent(compiler.currentElement, () => new Set()) | |
433 .add(target); | |
434 } | |
435 } | |
436 | |
437 void registerImpact(Element element, WorldImpact impact) { | 431 void registerImpact(Element element, WorldImpact impact) { |
438 if (compiler.options.dumpInfo) { | 432 if (compiler.options.dumpInfo) { |
439 impacts[element] = impact; | 433 impacts[element] = impact; |
440 } | 434 } |
441 } | 435 } |
442 | 436 |
443 void unregisterImpact(var impactSource) { | 437 void unregisterImpact(var impactSource) { |
444 impacts.remove(impactSource); | 438 impacts.remove(impactSource); |
445 } | 439 } |
446 | 440 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 ..add(jsonBuffer.toString()) | 539 ..add(jsonBuffer.toString()) |
546 ..close(); | 540 ..close(); |
547 }); | 541 }); |
548 } | 542 } |
549 | 543 |
550 void dumpInfoJson(StringSink buffer, ClosedWorld closedWorld) { | 544 void dumpInfoJson(StringSink buffer, ClosedWorld closedWorld) { |
551 JsonEncoder encoder = const JsonEncoder.withIndent(' '); | 545 JsonEncoder encoder = const JsonEncoder.withIndent(' '); |
552 Stopwatch stopwatch = new Stopwatch(); | 546 Stopwatch stopwatch = new Stopwatch(); |
553 stopwatch.start(); | 547 stopwatch.start(); |
554 | 548 |
| 549 AllInfo result = infoCollector.result; |
| 550 |
555 // Recursively build links to function uses | 551 // Recursively build links to function uses |
556 Iterable<Element> functionElements = | 552 Iterable<Element> functionElements = |
557 infoCollector._elementToInfo.keys.where((k) => k is FunctionElement); | 553 infoCollector._elementToInfo.keys.where((k) => k is FunctionElement); |
558 for (FunctionElement element in functionElements) { | 554 for (FunctionElement element in functionElements) { |
559 FunctionInfo info = infoCollector._elementToInfo[element]; | 555 FunctionInfo info = infoCollector._elementToInfo[element]; |
560 Iterable<Selection> uses = getRetaining(element, closedWorld); | 556 Iterable<Selection> uses = getRetaining(element, closedWorld); |
561 // Don't bother recording an empty list of dependencies. | 557 // Don't bother recording an empty list of dependencies. |
562 for (Selection selection in uses) { | 558 for (Selection selection in uses) { |
563 // Don't register dart2js builtin functions that are not recorded. | 559 // Don't register dart2js builtin functions that are not recorded. |
564 Info useInfo = infoCollector._elementToInfo[selection.selectedElement]; | 560 Info useInfo = infoCollector._elementToInfo[selection.selectedElement]; |
565 if (useInfo == null) continue; | 561 if (useInfo == null) continue; |
566 info.uses.add(new DependencyInfo(useInfo, '${selection.mask}')); | 562 info.uses.add(new DependencyInfo(useInfo, '${selection.mask}')); |
567 } | 563 } |
568 } | 564 } |
| 565 |
| 566 // Recursively build links to field uses |
| 567 Iterable<Element> fieldElements = |
| 568 infoCollector._elementToInfo.keys.where((k) => k is FieldElement); |
| 569 for (FieldElement element in fieldElements) { |
| 570 FieldInfo info = infoCollector._elementToInfo[element]; |
| 571 Iterable<Selection> uses = getRetaining(element, closedWorld); |
| 572 // Don't bother recording an empty list of dependencies. |
| 573 for (Selection selection in uses) { |
| 574 Info useInfo = infoCollector._elementToInfo[selection.selectedElement]; |
| 575 if (useInfo == null) continue; |
| 576 info.uses.add(new DependencyInfo(useInfo, '${selection.mask}')); |
| 577 } |
| 578 } |
| 579 |
569 // Notify the impact strategy impacts are no longer needed for dump info. | 580 // Notify the impact strategy impacts are no longer needed for dump info. |
570 compiler.impactStrategy.onImpactUsed(IMPACT_USE); | 581 compiler.impactStrategy.onImpactUsed(IMPACT_USE); |
571 | 582 |
572 // Track dependencies that come from inlining. | 583 // Track dependencies that come from inlining. |
573 for (Element element in inlineMap.keys) { | 584 for (Element element in inlineMap.keys) { |
574 CodeInfo outerInfo = infoCollector._elementToInfo[element]; | 585 CodeInfo outerInfo = infoCollector._elementToInfo[element]; |
575 if (outerInfo == null) continue; | 586 if (outerInfo == null) continue; |
576 for (Element inlined in inlineMap[element]) { | 587 for (Element inlined in inlineMap[element]) { |
577 Info inlinedInfo = infoCollector._elementToInfo[inlined]; | 588 Info inlinedInfo = infoCollector._elementToInfo[inlined]; |
578 if (inlinedInfo == null) continue; | 589 if (inlinedInfo == null) continue; |
579 outerInfo.uses.add(new DependencyInfo(inlinedInfo, 'inlined')); | 590 outerInfo.uses.add(new DependencyInfo(inlinedInfo, 'inlined')); |
580 } | 591 } |
581 } | 592 } |
582 | 593 |
583 AllInfo result = infoCollector.result; | |
584 | |
585 for (Element element in _dependencies.keys) { | |
586 var a = infoCollector._elementToInfo[element]; | |
587 if (a == null) continue; | |
588 result.dependencies[a] = _dependencies[element] | |
589 .map((o) => infoCollector._elementToInfo[o]) | |
590 .where((o) => o != null) | |
591 .toList(); | |
592 } | |
593 | |
594 result.deferredFiles = compiler.deferredLoadTask.computeDeferredMap(); | 594 result.deferredFiles = compiler.deferredLoadTask.computeDeferredMap(); |
595 stopwatch.stop(); | 595 stopwatch.stop(); |
596 result.program = new ProgramInfo( | 596 result.program = new ProgramInfo( |
597 entrypoint: infoCollector._elementToInfo[compiler.mainFunction], | 597 entrypoint: infoCollector._elementToInfo[compiler.mainFunction], |
598 size: _programSize, | 598 size: _programSize, |
599 dart2jsVersion: | 599 dart2jsVersion: |
600 compiler.options.hasBuildId ? compiler.options.buildId : null, | 600 compiler.options.hasBuildId ? compiler.options.buildId : null, |
601 compilationMoment: new DateTime.now(), | 601 compilationMoment: new DateTime.now(), |
602 compilationDuration: compiler.measurer.wallClock.elapsed, | 602 compilationDuration: compiler.measurer.wallClock.elapsed, |
603 toJsonDuration: | 603 toJsonDuration: |
604 new Duration(milliseconds: stopwatch.elapsedMilliseconds), | 604 new Duration(milliseconds: stopwatch.elapsedMilliseconds), |
605 dumpInfoDuration: new Duration(milliseconds: this.timing), | 605 dumpInfoDuration: new Duration(milliseconds: this.timing), |
606 noSuchMethodEnabled: compiler.backend.enabledNoSuchMethod, | 606 noSuchMethodEnabled: compiler.backend.enabledNoSuchMethod, |
607 minified: compiler.options.enableMinification); | 607 minified: compiler.options.enableMinification); |
608 | 608 |
609 ChunkedConversionSink<Object> sink = encoder.startChunkedConversion( | 609 ChunkedConversionSink<Object> sink = encoder.startChunkedConversion( |
610 new StringConversionSink.fromStringSink(buffer)); | 610 new StringConversionSink.fromStringSink(buffer)); |
611 sink.add(new AllInfoJsonCodec().encode(result)); | 611 sink.add(new AllInfoJsonCodec().encode(result)); |
612 compiler.reporter.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, { | 612 compiler.reporter.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, { |
613 'text': "View the dumped .info.json file at " | 613 'text': "View the dumped .info.json file at " |
614 "https://dart-lang.github.io/dump-info-visualizer" | 614 "https://dart-lang.github.io/dump-info-visualizer" |
615 }); | 615 }); |
616 } | 616 } |
617 } | 617 } |
OLD | NEW |