Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: pkg/analyzer/lib/src/task/driver.dart

Issue 1406983007: Compute and display tasks input timings. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/analysis_server/lib/src/status/get_handler.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/status/get_handler.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698