OLD | NEW |
---|---|
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 analyzer.src.task.driver; | 5 library analyzer.src.task.driver; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 | 9 |
10 import 'package:analyzer/src/context/cache.dart'; | 10 import 'package:analyzer/src/context/cache.dart'; |
11 import 'package:analyzer/src/generated/engine.dart' | 11 import 'package:analyzer/src/generated/engine.dart' |
12 hide AnalysisTask, AnalysisContextImpl, WorkManager; | 12 hide AnalysisTask, AnalysisContextImpl, WorkManager; |
13 import 'package:analyzer/src/generated/java_engine.dart'; | 13 import 'package:analyzer/src/generated/java_engine.dart'; |
14 import 'package:analyzer/src/generated/resolver.dart'; | 14 import 'package:analyzer/src/generated/resolver.dart'; |
15 import 'package:analyzer/src/generated/utilities_general.dart'; | 15 import 'package:analyzer/src/generated/utilities_general.dart'; |
16 import 'package:analyzer/src/task/inputs.dart'; | 16 import 'package:analyzer/src/task/inputs.dart'; |
17 import 'package:analyzer/src/task/manager.dart'; | 17 import 'package:analyzer/src/task/manager.dart'; |
18 import 'package:analyzer/task/model.dart'; | 18 import 'package:analyzer/task/model.dart'; |
19 | 19 |
20 final PerformanceTag workOrderMoveNextPerfTag = | 20 final PerformanceTag workOrderMoveNextPerformanceTag = |
21 new PerformanceTag('WorkOrder.moveNext'); | 21 new PerformanceTag('WorkOrder.moveNext'); |
22 | 22 |
23 /** | 23 /** |
24 * An object that is used to cause analysis to be performed until all of the | 24 * An object that is used to cause analysis to be performed until all of the |
25 * required analysis information has been computed. | 25 * required analysis information has been computed. |
26 */ | 26 */ |
27 class AnalysisDriver { | 27 class AnalysisDriver { |
28 /** | 28 /** |
29 * The task manager used to figure out how to compute analysis results. | 29 * The task manager used to figure out how to compute analysis results. |
30 */ | 30 */ |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
513 * if [nodes] has multiple elements, this will always be `true`. However, if | 513 * if [nodes] has multiple elements, this will always be `true`. However, if |
514 * [nodes] has exactly one element, this may be either `true` or `false` | 514 * [nodes] has exactly one element, this may be either `true` or `false` |
515 * depending on whether the node has a dependency on itself. | 515 * depending on whether the node has a dependency on itself. |
516 */ | 516 */ |
517 final bool containsCycle; | 517 final bool containsCycle; |
518 | 518 |
519 StronglyConnectedComponent(this.nodes, this.containsCycle); | 519 StronglyConnectedComponent(this.nodes, this.containsCycle); |
520 } | 520 } |
521 | 521 |
522 /** | 522 /** |
523 * A description of a single anaysis task that can be performed to advance | 523 * A description of a single analysis task that can be performed to advance |
524 * analysis. | 524 * analysis. |
525 */ | 525 */ |
526 class WorkItem { | 526 class WorkItem { |
527 /** | 527 /** |
528 * A table mapping the names of analysis tasks to the number of times each | |
529 * kind of task has been performed. | |
530 */ | |
531 static final Map<String, int> countMap = new HashMap<String, int>(); | |
532 | |
533 /** | |
534 * A table mapping the names of analysis tasks to stopwatches used to compute | |
535 * how much time was spent between creating an item and creating (for | |
536 * performing) of each kind of task | |
537 */ | |
538 static final Map<String, Stopwatch> stopwatchMap = | |
539 new HashMap<String, Stopwatch>(); | |
540 | |
541 /** | |
528 * The context in which the task will be performed. | 542 * The context in which the task will be performed. |
529 */ | 543 */ |
530 final InternalAnalysisContext context; | 544 final InternalAnalysisContext context; |
531 | 545 |
532 /** | 546 /** |
533 * The target for which a task is to be performed. | 547 * The target for which a task is to be performed. |
534 */ | 548 */ |
535 final AnalysisTarget target; | 549 final AnalysisTarget target; |
536 | 550 |
537 /** | 551 /** |
538 * A description of the task to be performed. | 552 * A description of the task to be performed. |
539 */ | 553 */ |
540 final TaskDescriptor descriptor; | 554 final TaskDescriptor descriptor; |
541 | 555 |
542 /** | 556 /** |
543 * The [ResultDescriptor] which was led to this work item being spawned. | 557 * The [ResultDescriptor] which was led to this work item being spawned. |
544 */ | 558 */ |
545 final ResultDescriptor spawningResult; | 559 final ResultDescriptor spawningResult; |
546 | 560 |
547 /** | 561 /** |
562 * The current inputs computing stopwatch. | |
563 */ | |
564 Stopwatch stopwatch; | |
565 | |
566 /** | |
548 * An iterator used to iterate over the descriptors of the inputs to the task, | 567 * An iterator used to iterate over the descriptors of the inputs to the task, |
549 * or `null` if all of the inputs have been collected and the task can be | 568 * or `null` if all of the inputs have been collected and the task can be |
550 * created. | 569 * created. |
551 */ | 570 */ |
552 TaskInputBuilder builder; | 571 TaskInputBuilder builder; |
553 | 572 |
554 /** | 573 /** |
555 * The [TargetedResult]s outputs of this task depends on. | 574 * The [TargetedResult]s outputs of this task depends on. |
556 */ | 575 */ |
557 final HashSet<TargetedResult> inputTargetedResults = | 576 final HashSet<TargetedResult> inputTargetedResults = |
(...skipping 29 matching lines...) Expand all Loading... | |
587 identical(target, AnalysisContextTarget.request) | 606 identical(target, AnalysisContextTarget.request) |
588 ? new AnalysisContextTarget(context) | 607 ? new AnalysisContextTarget(context) |
589 : target; | 608 : target; |
590 Map<String, TaskInput> inputDescriptors = | 609 Map<String, TaskInput> inputDescriptors = |
591 descriptor.createTaskInputs(actualTarget); | 610 descriptor.createTaskInputs(actualTarget); |
592 builder = new TopLevelTaskInputBuilder(inputDescriptors); | 611 builder = new TopLevelTaskInputBuilder(inputDescriptors); |
593 if (!builder.moveNext()) { | 612 if (!builder.moveNext()) { |
594 builder = null; | 613 builder = null; |
595 } | 614 } |
596 inputs = new HashMap<String, dynamic>(); | 615 inputs = new HashMap<String, dynamic>(); |
616 // Update performance counters. | |
617 { | |
618 stopwatch = stopwatchMap[descriptor.name]; | |
Brian Wilkerson
2015/10/23 16:27:11
The descriptors are long-lived and unique, so you
| |
619 if (stopwatch == null) { | |
620 stopwatch = new Stopwatch(); | |
621 stopwatchMap[descriptor.name] = stopwatch; | |
622 } | |
623 stopwatch.start(); | |
624 } | |
625 { | |
626 int count = countMap[descriptor.name]; | |
627 countMap[descriptor.name] = count == null ? 1 : count + 1; | |
628 } | |
597 } | 629 } |
598 | 630 |
599 @override | 631 @override |
600 int get hashCode => | 632 int get hashCode => |
601 JenkinsSmiHash.hash2(descriptor.hashCode, target.hashCode); | 633 JenkinsSmiHash.hash2(descriptor.hashCode, target.hashCode); |
602 | 634 |
603 @override | 635 @override |
604 bool operator ==(other) { | 636 bool operator ==(other) { |
605 if (other is WorkItem) { | 637 if (other is WorkItem) { |
606 return this.descriptor == other.descriptor && this.target == other.target; | 638 return this.descriptor == other.descriptor && this.target == other.target; |
607 } else { | 639 } else { |
608 return false; | 640 return false; |
609 } | 641 } |
610 } | 642 } |
611 | 643 |
612 /** | 644 /** |
613 * Build the task represented by this work item. | 645 * Build the task represented by this work item. |
614 */ | 646 */ |
615 AnalysisTask buildTask() { | 647 AnalysisTask buildTask() { |
648 stopwatch.stop(); | |
616 if (builder != null) { | 649 if (builder != null) { |
617 throw new StateError("some inputs have not been computed"); | 650 throw new StateError("some inputs have not been computed"); |
618 } | 651 } |
619 AnalysisTask task = descriptor.createTask(context, target, inputs); | 652 AnalysisTask task = descriptor.createTask(context, target, inputs); |
620 task.dependencyCycle = dependencyCycle; | 653 task.dependencyCycle = dependencyCycle; |
621 return task; | 654 return task; |
622 } | 655 } |
623 | 656 |
624 /** | 657 /** |
625 * Gather all of the inputs needed to perform the task. | 658 * Gather all of the inputs needed to perform the task. |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
723 WorkItem get current { | 756 WorkItem get current { |
724 if (currentItems == null) { | 757 if (currentItems == null) { |
725 return null; | 758 return null; |
726 } else { | 759 } else { |
727 return currentItems.last; | 760 return currentItems.last; |
728 } | 761 } |
729 } | 762 } |
730 | 763 |
731 @override | 764 @override |
732 bool moveNext() { | 765 bool moveNext() { |
733 return workOrderMoveNextPerfTag.makeCurrentWhile(() { | 766 return workOrderMoveNextPerformanceTag.makeCurrentWhile(() { |
734 if (currentItems != null && currentItems.length > 1) { | 767 if (currentItems != null && currentItems.length > 1) { |
735 // Yield more items. | 768 // Yield more items. |
736 currentItems.removeLast(); | 769 currentItems.removeLast(); |
737 return true; | 770 return true; |
738 } else { | 771 } else { |
739 // Get a new strongly connected component. | 772 // Get a new strongly connected component. |
740 StronglyConnectedComponent<WorkItem> nextStronglyConnectedComponent = | 773 StronglyConnectedComponent<WorkItem> nextStronglyConnectedComponent = |
741 _dependencyWalker.getNextStronglyConnectedComponent(); | 774 _dependencyWalker.getNextStronglyConnectedComponent(); |
742 if (nextStronglyConnectedComponent == null) { | 775 if (nextStronglyConnectedComponent == null) { |
743 currentItems = null; | 776 currentItems = null; |
744 return false; | 777 return false; |
745 } | 778 } |
746 currentItems = nextStronglyConnectedComponent.nodes; | 779 currentItems = nextStronglyConnectedComponent.nodes; |
747 if (nextStronglyConnectedComponent.containsCycle) { | 780 if (nextStronglyConnectedComponent.containsCycle) { |
748 // A cycle has been found. | 781 // A cycle has been found. |
749 for (WorkItem item in currentItems) { | 782 for (WorkItem item in currentItems) { |
750 item.dependencyCycle = currentItems.toList(); | 783 item.dependencyCycle = currentItems.toList(); |
751 } | 784 } |
752 } else { | 785 } else { |
753 assert(currentItems.length == 1); | 786 assert(currentItems.length == 1); |
754 } | 787 } |
755 return true; | 788 return true; |
756 } | 789 } |
757 }); | 790 }); |
758 } | 791 } |
759 } | 792 } |
760 | 793 |
761 /** | 794 /** |
762 * Specilaization of [CycleAwareDependencyWalker] for use by [WorkOrder]. | 795 * Specialization of [CycleAwareDependencyWalker] for use by [WorkOrder]. |
763 */ | 796 */ |
764 class _WorkOrderDependencyWalker extends CycleAwareDependencyWalker<WorkItem> { | 797 class _WorkOrderDependencyWalker extends CycleAwareDependencyWalker<WorkItem> { |
765 /** | 798 /** |
766 * The task manager used to build work items. | 799 * The task manager used to build work items. |
767 */ | 800 */ |
768 final TaskManager taskManager; | 801 final TaskManager taskManager; |
769 | 802 |
770 _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode) | 803 _WorkOrderDependencyWalker(this.taskManager, WorkItem startingNode) |
771 : super(startingNode); | 804 : super(startingNode); |
772 | 805 |
773 @override | 806 @override |
774 WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) { | 807 WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) { |
775 return node.gatherInputs(taskManager, skipInputs); | 808 return node.gatherInputs(taskManager, skipInputs); |
776 } | 809 } |
777 } | 810 } |
OLD | NEW |