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