Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 | 6 |
| 7 import 'package:front_end/incremental_kernel_generator.dart'; | 7 import 'package:front_end/incremental_kernel_generator.dart'; |
| 8 import 'package:front_end/src/base/performace_logger.dart'; | 8 import 'package:front_end/src/base/performace_logger.dart'; |
| 9 import 'package:front_end/src/base/processed_options.dart'; | 9 import 'package:front_end/src/base/processed_options.dart'; |
| 10 import 'package:front_end/src/fasta/uri_translator.dart'; | 10 import 'package:front_end/src/fasta/uri_translator.dart'; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 | 29 |
| 30 /// The URI of the program entry point. | 30 /// The URI of the program entry point. |
| 31 final Uri _entryPoint; | 31 final Uri _entryPoint; |
| 32 | 32 |
| 33 /// The function to notify when files become used or unused, or `null`. | 33 /// The function to notify when files become used or unused, or `null`. |
| 34 final WatchUsedFilesFn _watchFn; | 34 final WatchUsedFilesFn _watchFn; |
| 35 | 35 |
| 36 /// The [KernelDriver] that is used to compute kernels. | 36 /// The [KernelDriver] that is used to compute kernels. |
| 37 KernelDriver _driver; | 37 KernelDriver _driver; |
| 38 | 38 |
| 39 /// Whether [computeDelta] is executing. | |
| 40 bool _isComputeDeltaExecuting = false; | |
| 41 | |
| 39 /// The current signatures for libraries. | 42 /// The current signatures for libraries. |
| 40 final Map<Uri, String> _currentSignatures = {}; | 43 final Map<Uri, String> _currentSignatures = {}; |
| 41 | 44 |
| 42 /// The signatures for libraries produced by the last [computeDelta], or | 45 /// The signatures for libraries produced by the last [computeDelta], or |
| 43 /// `null` if the last delta was either accepted or rejected. | 46 /// `null` if the last delta was either accepted or rejected. |
| 44 Map<Uri, String> _lastSignatures; | 47 Map<Uri, String> _lastSignatures; |
| 45 | 48 |
| 46 /// The object that provides additional information for tests. | 49 /// The object that provides additional information for tests. |
| 47 _TestView _testView; | 50 _TestView _testView; |
| 48 | 51 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 70 | 73 |
| 71 @override | 74 @override |
| 72 void acceptLastDelta() { | 75 void acceptLastDelta() { |
| 73 _throwIfNoLastDelta(); | 76 _throwIfNoLastDelta(); |
| 74 _currentSignatures.addAll(_lastSignatures); | 77 _currentSignatures.addAll(_lastSignatures); |
| 75 _lastSignatures = null; | 78 _lastSignatures = null; |
| 76 } | 79 } |
| 77 | 80 |
| 78 @override | 81 @override |
| 79 Future<DeltaProgram> computeDelta() async { | 82 Future<DeltaProgram> computeDelta() async { |
| 80 if (_lastSignatures != null) { | 83 if (_isComputeDeltaExecuting) { |
| 81 throw new StateError( | 84 throw new StateError( |
| 82 'The last delta must be either accepted or rejected.'); | 85 'Another computeDelta() invocation is still executing.'); |
| 83 } | 86 } |
| 84 _lastSignatures = {}; | 87 _isComputeDeltaExecuting = true; |
| 85 | 88 |
| 86 return await _logger.runAsync('Compute delta', () async { | 89 try { |
| 87 KernelResult kernelResult = await _driver.getKernel(_entryPoint); | 90 if (_lastSignatures != null) { |
| 88 List<LibraryCycleResult> results = kernelResult.results; | 91 throw new StateError( |
| 92 'The last delta must be either accepted or rejected.'); | |
| 93 } | |
| 94 _lastSignatures = {}; | |
| 89 | 95 |
| 90 // The file graph might have changed, perform GC. | 96 return await _logger.runAsync('Compute delta', () async { |
| 91 await _gc(); | 97 KernelResult kernelResult = await _driver.getKernel(_entryPoint); |
| 98 List<LibraryCycleResult> results = kernelResult.results; | |
| 92 | 99 |
| 93 // The set of affected library cycles (have different signatures). | 100 // The file graph might have changed, perform GC. |
| 94 final affectedLibraryCycles = new Set<LibraryCycle>(); | 101 await _gc(); |
| 95 for (LibraryCycleResult result in results) { | 102 |
| 96 for (Library library in result.kernelLibraries) { | 103 // The set of affected library cycles (have different signatures). |
| 97 Uri uri = library.importUri; | 104 final affectedLibraryCycles = new Set<LibraryCycle>(); |
| 98 if (_currentSignatures[uri] != result.signature) { | 105 for (LibraryCycleResult result in results) { |
| 99 _lastSignatures[uri] = result.signature; | 106 for (Library library in result.kernelLibraries) { |
| 100 affectedLibraryCycles.add(result.cycle); | 107 Uri uri = library.importUri; |
| 108 if (_currentSignatures[uri] != result.signature) { | |
| 109 _lastSignatures[uri] = result.signature; | |
| 110 affectedLibraryCycles.add(result.cycle); | |
| 111 } | |
| 101 } | 112 } |
| 102 } | 113 } |
| 103 } | |
| 104 | 114 |
| 105 // The set of affected library cycles (have different signatures), | 115 // The set of affected library cycles (have different signatures), |
| 106 // or libraries that import or export affected libraries (so VM might | 116 // or libraries that import or export affected libraries (so VM might |
| 107 // have inlined some code from affected libraries into them). | 117 // have inlined some code from affected libraries into them). |
| 108 final vmRequiredLibraryCycles = new Set<LibraryCycle>(); | 118 final vmRequiredLibraryCycles = new Set<LibraryCycle>(); |
| 109 | 119 |
| 110 void gatherVmRequiredLibraryCycles(LibraryCycle cycle) { | 120 void gatherVmRequiredLibraryCycles(LibraryCycle cycle) { |
| 111 if (vmRequiredLibraryCycles.add(cycle)) { | 121 if (vmRequiredLibraryCycles.add(cycle)) { |
| 112 cycle.directUsers.forEach(gatherVmRequiredLibraryCycles); | 122 cycle.directUsers.forEach(gatherVmRequiredLibraryCycles); |
| 113 } | |
| 114 } | |
| 115 | |
| 116 affectedLibraryCycles.forEach(gatherVmRequiredLibraryCycles); | |
| 117 | |
| 118 // Add required libraries. | |
| 119 Program program = new Program(nameRoot: kernelResult.nameRoot); | |
| 120 for (LibraryCycleResult result in results) { | |
| 121 if (vmRequiredLibraryCycles.contains(result.cycle)) { | |
| 122 for (Library library in result.kernelLibraries) { | |
| 123 program.libraries.add(library); | |
| 124 library.parent = program; | |
| 125 } | 123 } |
| 126 } | 124 } |
| 127 } | |
| 128 | 125 |
| 129 // Set the main method. | 126 affectedLibraryCycles.forEach(gatherVmRequiredLibraryCycles); |
| 130 if (program.libraries.isNotEmpty) { | 127 |
| 131 for (Library library in results.last.kernelLibraries) { | 128 // Add required libraries. |
| 132 if (library.importUri == _entryPoint) { | 129 Program program = new Program(nameRoot: kernelResult.nameRoot); |
| 133 program.mainMethod = library.procedures.firstWhere( | 130 for (LibraryCycleResult result in results) { |
| 134 (procedure) => procedure.name.name == 'main', | 131 if (vmRequiredLibraryCycles.contains(result.cycle)) { |
| 135 orElse: () => null); | 132 for (Library library in result.kernelLibraries) { |
| 136 break; | 133 program.libraries.add(library); |
| 134 library.parent = program; | |
| 135 } | |
| 137 } | 136 } |
| 138 } | 137 } |
| 139 } | |
| 140 | 138 |
| 141 return new DeltaProgram(program); | 139 // Set the main method. |
| 142 }); | 140 if (program.libraries.isNotEmpty) { |
| 141 for (Library library in results.last.kernelLibraries) { | |
| 142 if (library.importUri == _entryPoint) { | |
| 143 program.mainMethod = library.procedures.firstWhere( | |
| 144 (procedure) => procedure.name.name == 'main', | |
| 145 orElse: () => null); | |
| 146 break; | |
| 147 } | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 return new DeltaProgram(program); | |
| 152 }); | |
| 153 } finally { | |
| 154 _isComputeDeltaExecuting = false; | |
| 155 } | |
| 143 } | 156 } |
| 144 | 157 |
| 145 @override | 158 @override |
| 146 void invalidate(Uri uri) { | 159 void invalidate(Uri uri) { |
| 147 _driver.invalidate(uri); | 160 _driver.invalidate(uri); |
| 148 } | 161 } |
| 149 | 162 |
| 150 @override | 163 @override |
| 151 void rejectLastDelta() { | 164 void rejectLastDelta() { |
| 152 _throwIfNoLastDelta(); | 165 _throwIfNoLastDelta(); |
| 153 _lastSignatures = null; | 166 _lastSignatures = null; |
| 154 } | 167 } |
| 155 | 168 |
| 156 /// TODO(scheglov) document | 169 /// Find files which are not referenced from the entry point and report |
| 170 /// them to the watch function. | |
| 157 Future<Null> _gc() async { | 171 Future<Null> _gc() async { |
| 158 var removedFiles = _driver.fsState.gc(_entryPoint); | 172 var removedFiles = _driver.fsState.gc(_entryPoint); |
| 159 if (removedFiles.isNotEmpty && _watchFn != null) { | 173 if (removedFiles.isNotEmpty && _watchFn != null) { |
| 160 for (var removedFile in removedFiles) { | 174 for (var removedFile in removedFiles) { |
| 161 await _watchFn(removedFile.fileUri, false); | 175 await _watchFn(removedFile.fileUri, false); |
| 162 } | 176 } |
| 163 } | 177 } |
| 164 } | 178 } |
| 165 | 179 |
| 166 /// Throw [StateError] if [_lastSignatures] is `null`, i.e. there is no | 180 /// Throw [StateError] if [_lastSignatures] is `null`, i.e. there is no |
| 167 /// last delta - it either has not been computed yet, or has been already | 181 /// last delta - it either has not been computed yet, or has been already |
| 168 /// accepted or rejected. | 182 /// accepted or rejected. |
| 169 void _throwIfNoLastDelta() { | 183 void _throwIfNoLastDelta() { |
| 170 if (_lastSignatures == null) { | 184 if (_lastSignatures == null) { |
|
Siggi Cherem (dart-lang)
2017/08/10 22:43:29
could we also check here that _isComputeDeltaExecu
scheglov
2017/08/10 23:46:49
Done.
| |
| 171 throw new StateError( | 185 throw new StateError( |
| 172 'The last delta has been already accepted or rejected.'); | 186 'The last delta has been already accepted or rejected.'); |
| 173 } | 187 } |
| 174 } | 188 } |
| 175 } | 189 } |
| 176 | 190 |
| 177 @visibleForTesting | 191 @visibleForTesting |
| 178 class _TestView { | 192 class _TestView { |
| 179 final IncrementalKernelGeneratorImpl _generator; | 193 final IncrementalKernelGeneratorImpl _generator; |
| 180 | 194 |
| 181 _TestView(this._generator); | 195 _TestView(this._generator); |
| 182 | 196 |
| 183 /// The [KernelDriver] that is used to actually compile. | 197 /// The [KernelDriver] that is used to actually compile. |
| 184 KernelDriver get driver => _generator._driver; | 198 KernelDriver get driver => _generator._driver; |
| 185 } | 199 } |
| OLD | NEW |