OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:collection'; | 6 import 'dart:collection'; |
7 import 'dart:typed_data'; | 7 import 'dart:typed_data'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement; | 10 import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement; |
(...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
970 _drivers.remove(driver); | 970 _drivers.remove(driver); |
971 _statusSupport.transitionToAnalyzing(); | 971 _statusSupport.transitionToAnalyzing(); |
972 _hasWork.notify(); | 972 _hasWork.notify(); |
973 } | 973 } |
974 | 974 |
975 /** | 975 /** |
976 * Run infinitely analysis cycle, selecting the drivers with the highest | 976 * Run infinitely analysis cycle, selecting the drivers with the highest |
977 * priority first. | 977 * priority first. |
978 */ | 978 */ |
979 Future<Null> _run() async { | 979 Future<Null> _run() async { |
980 Stopwatch timer = new Stopwatch()..start(); | |
980 PerformanceLogSection analysisSection; | 981 PerformanceLogSection analysisSection; |
981 while (true) { | 982 while (true) { |
982 // Pump the event queue to allow IO and other asynchronous data | 983 // Pump the event queue to allow IO and other asynchronous data |
983 // processing while analysis is active. For example Analysis Server | 984 // processing while analysis is active. For example Analysis Server |
984 // needs to be able to process `updateContent` or `setPriorityFiles` | 985 // needs to be able to process `updateContent` or `setPriorityFiles` |
985 // requests while background analysis is in progress. | 986 // requests while background analysis is in progress. |
986 // | 987 // |
987 // The number of pumpings is arbitrary, might be changed if we see that | 988 // The number of pumpings is arbitrary, might be changed if we see that |
988 // analysis or other data processing tasks are starving. Ideally we | 989 // analysis or other data processing tasks are starving. Ideally we |
989 // would need to be able to set priority of (continuous) asynchronous | 990 // would need to be able to set priority of (continuous) asynchronous |
990 // tasks. | 991 // tasks. |
991 await _pumpEventQueue(128); | 992 // |
993 // Relinquishing execution flow and running event loop after every task | |
994 // has too much overhead. Instead we use a fixed length of time, so we | |
995 // can spend less time overall and still respond quick enough. | |
996 if (timer.elapsedMilliseconds > 2) { | |
Brian Wilkerson
2016/12/01 14:36:38
I think it would be a good thing to define some co
scheglov
2016/12/01 16:55:06
Done.
| |
997 await _pumpEventQueue(128); | |
998 timer.reset(); | |
999 } | |
992 | 1000 |
993 await _hasWork.signal; | 1001 await _hasWork.signal; |
994 | 1002 |
995 if (analysisSection == null) { | 1003 if (analysisSection == null) { |
996 analysisSection = _logger.enter('Analyzing'); | 1004 analysisSection = _logger.enter('Analyzing'); |
997 } | 1005 } |
998 | 1006 |
999 // Find the driver with the highest priority. | 1007 // Find the driver with the highest priority. |
1000 AnalysisDriver bestDriver; | 1008 AnalysisDriver bestDriver; |
1001 AnalysisDriverPriority bestPriority = AnalysisDriverPriority.nothing; | 1009 AnalysisDriverPriority bestPriority = AnalysisDriverPriority.nothing; |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1259 final String name; | 1267 final String name; |
1260 final Completer<List<String>> completer = new Completer<List<String>>(); | 1268 final Completer<List<String>> completer = new Completer<List<String>>(); |
1261 | 1269 |
1262 final List<String> referencingFiles = <String>[]; | 1270 final List<String> referencingFiles = <String>[]; |
1263 final Set<String> checkedFiles = new Set<String>(); | 1271 final Set<String> checkedFiles = new Set<String>(); |
1264 final List<String> filesToCheck = <String>[]; | 1272 final List<String> filesToCheck = <String>[]; |
1265 | 1273 |
1266 _FilesReferencingNameTask(this.driver, this.name); | 1274 _FilesReferencingNameTask(this.driver, this.name); |
1267 | 1275 |
1268 /** | 1276 /** |
1269 * Perform work for a fixed length of time, and either complete the | 1277 * Perform a single piece of work, and either complete the [completer] and |
1270 * [completer] and return `true` to indicate that the task is done, return | 1278 * return `true` to indicate that the task is done, return `false` to indicate |
1271 * `false` to indicate that the task should continue to be run. | 1279 * that the task should continue to be run. |
1272 * | |
1273 * Relinquishing execution flow and running event loop after every file | |
1274 * works, but has too much overhead. Instead we use a fixed length of time, | |
1275 * so we can spend less time overall and keep quick enough response time. | |
1276 */ | 1280 */ |
1277 Future<bool> perform() async { | 1281 Future<bool> perform() async { |
1278 Stopwatch timer = new Stopwatch()..start(); | 1282 // Prepare files to check. |
1279 while (timer.elapsedMilliseconds < 5) { | 1283 if (filesToCheck.isEmpty) { |
1280 // Prepare files to check. | 1284 Set<String> newFiles = driver.addedFiles.difference(checkedFiles); |
1281 if (filesToCheck.isEmpty) { | 1285 filesToCheck.addAll(newFiles); |
1282 Set<String> newFiles = driver.addedFiles.difference(checkedFiles); | 1286 } |
1283 filesToCheck.addAll(newFiles); | |
1284 } | |
1285 | 1287 |
1286 // If no more files to check, complete and done. | 1288 // If no more files to check, complete and done. |
1287 if (filesToCheck.isEmpty) { | 1289 if (filesToCheck.isEmpty) { |
1288 completer.complete(referencingFiles); | 1290 completer.complete(referencingFiles); |
1289 return true; | 1291 return true; |
1290 } | 1292 } |
1291 | 1293 |
1292 // Check the next file. | 1294 // Check the next file. |
1293 String path = filesToCheck.removeLast(); | 1295 String path = filesToCheck.removeLast(); |
1294 FileState file = driver._fsState.getFileForPath(path); | 1296 FileState file = driver._fsState.getFileForPath(path); |
1295 if (file.referencedNames.contains(name)) { | 1297 if (file.referencedNames.contains(name)) { |
1296 referencingFiles.add(path); | 1298 referencingFiles.add(path); |
1297 } | |
1298 checkedFiles.add(path); | |
1299 } | 1299 } |
1300 checkedFiles.add(path); | |
1300 | 1301 |
1301 // We're not done yet. | 1302 // We're not done yet. |
1302 return false; | 1303 return false; |
1303 } | 1304 } |
1304 } | 1305 } |
1305 | 1306 |
1306 /** | 1307 /** |
1307 * TODO(scheglov) document | 1308 * TODO(scheglov) document |
1308 */ | 1309 */ |
1309 class _LibraryContext { | 1310 class _LibraryContext { |
1310 final FileState file; | 1311 final FileState file; |
1311 final SummaryDataStore store; | 1312 final SummaryDataStore store; |
1312 _LibraryContext(this.file, this.store); | 1313 _LibraryContext(this.file, this.store); |
1313 } | 1314 } |
OLD | NEW |