Chromium Code Reviews| Index: pkg/front_end/lib/src/incremental_kernel_generator_impl.dart |
| diff --git a/pkg/front_end/lib/src/incremental_kernel_generator_impl.dart b/pkg/front_end/lib/src/incremental_kernel_generator_impl.dart |
| index 77cd524f5212305080fb4ea12fa7c1627e3e0b83..caf656e07595d8243c8b8b0fb90e6c18656fda60 100644 |
| --- a/pkg/front_end/lib/src/incremental_kernel_generator_impl.dart |
| +++ b/pkg/front_end/lib/src/incremental_kernel_generator_impl.dart |
| @@ -21,8 +21,14 @@ import 'package:meta/meta.dart'; |
| /// used to obtain resolved ASTs, and these are fed into kernel code generation |
| /// logic. |
| class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { |
| - /// The version of data format, should be incremented on every format change. |
| - static const int DATA_VERSION = 1; |
| + static const MSG_PENDING_COMPUTE = |
|
Siggi Cherem (dart-lang)
2017/08/11 00:44:52
not for this CL: even if we don't report them on t
scheglov
2017/08/11 04:50:40
Yes, is seems like it might be useful to put into
|
| + 'Another computeDelta() invocation is still executing.'; |
|
Siggi Cherem (dart-lang)
2017/08/11 00:44:52
Consider: Another => A
(since now this message is
scheglov
2017/08/11 04:50:40
Done.
|
| + |
| + static const MSG_NO_LAST_DELTA = |
| + 'The last delta has been already accepted or rejected.'; |
| + |
| + static const MSG_HAS_LAST_DELTA = |
| + 'The last delta must be either accepted or rejected.'; |
| /// The logger to report compilation progress. |
| final PerformanceLog _logger; |
| @@ -36,6 +42,9 @@ class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { |
| /// The [KernelDriver] that is used to compute kernels. |
| KernelDriver _driver; |
| + /// Whether [computeDelta] is executing. |
| + bool _isComputeDeltaExecuting = false; |
| + |
| /// The current signatures for libraries. |
| final Map<Uri, String> _currentSignatures = {}; |
| @@ -76,69 +85,78 @@ class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { |
| } |
| @override |
| - Future<DeltaProgram> computeDelta() async { |
| + Future<DeltaProgram> computeDelta() { |
| + if (_isComputeDeltaExecuting) { |
| + throw new StateError(MSG_PENDING_COMPUTE); |
| + } |
| + |
| if (_lastSignatures != null) { |
| - throw new StateError( |
| - 'The last delta must be either accepted or rejected.'); |
| + throw new StateError(MSG_HAS_LAST_DELTA); |
| } |
| _lastSignatures = {}; |
| - return await _logger.runAsync('Compute delta', () async { |
| - KernelResult kernelResult = await _driver.getKernel(_entryPoint); |
| - List<LibraryCycleResult> results = kernelResult.results; |
| - |
| - // The file graph might have changed, perform GC. |
| - await _gc(); |
| - |
| - // The set of affected library cycles (have different signatures). |
| - final affectedLibraryCycles = new Set<LibraryCycle>(); |
| - for (LibraryCycleResult result in results) { |
| - for (Library library in result.kernelLibraries) { |
| - Uri uri = library.importUri; |
| - if (_currentSignatures[uri] != result.signature) { |
| - _lastSignatures[uri] = result.signature; |
| - affectedLibraryCycles.add(result.cycle); |
| + _isComputeDeltaExecuting = true; |
| + |
| + return _logger.runAsync('Compute delta', () async { |
| + try { |
| + KernelResult kernelResult = await _driver.getKernel(_entryPoint); |
| + List<LibraryCycleResult> results = kernelResult.results; |
| + |
| + // The file graph might have changed, perform GC. |
| + await _gc(); |
| + |
| + // The set of affected library cycles (have different signatures). |
| + final affectedLibraryCycles = new Set<LibraryCycle>(); |
| + for (LibraryCycleResult result in results) { |
| + for (Library library in result.kernelLibraries) { |
| + Uri uri = library.importUri; |
| + if (_currentSignatures[uri] != result.signature) { |
| + _lastSignatures[uri] = result.signature; |
| + affectedLibraryCycles.add(result.cycle); |
| + } |
| } |
| } |
| - } |
| - // The set of affected library cycles (have different signatures), |
| - // or libraries that import or export affected libraries (so VM might |
| - // have inlined some code from affected libraries into them). |
| - final vmRequiredLibraryCycles = new Set<LibraryCycle>(); |
| + // The set of affected library cycles (have different signatures), |
| + // or libraries that import or export affected libraries (so VM might |
| + // have inlined some code from affected libraries into them). |
| + final vmRequiredLibraryCycles = new Set<LibraryCycle>(); |
| - void gatherVmRequiredLibraryCycles(LibraryCycle cycle) { |
| - if (vmRequiredLibraryCycles.add(cycle)) { |
| - cycle.directUsers.forEach(gatherVmRequiredLibraryCycles); |
| + void gatherVmRequiredLibraryCycles(LibraryCycle cycle) { |
| + if (vmRequiredLibraryCycles.add(cycle)) { |
| + cycle.directUsers.forEach(gatherVmRequiredLibraryCycles); |
| + } |
| } |
| - } |
| - affectedLibraryCycles.forEach(gatherVmRequiredLibraryCycles); |
| + affectedLibraryCycles.forEach(gatherVmRequiredLibraryCycles); |
| - // Add required libraries. |
| - Program program = new Program(nameRoot: kernelResult.nameRoot); |
| - for (LibraryCycleResult result in results) { |
| - if (vmRequiredLibraryCycles.contains(result.cycle)) { |
| - for (Library library in result.kernelLibraries) { |
| - program.libraries.add(library); |
| - library.parent = program; |
| + // Add required libraries. |
| + Program program = new Program(nameRoot: kernelResult.nameRoot); |
| + for (LibraryCycleResult result in results) { |
| + if (vmRequiredLibraryCycles.contains(result.cycle)) { |
| + for (Library library in result.kernelLibraries) { |
| + program.libraries.add(library); |
| + library.parent = program; |
| + } |
| } |
| } |
| - } |
| - // Set the main method. |
| - if (program.libraries.isNotEmpty) { |
| - for (Library library in results.last.kernelLibraries) { |
| - if (library.importUri == _entryPoint) { |
| - program.mainMethod = library.procedures.firstWhere( |
| - (procedure) => procedure.name.name == 'main', |
| - orElse: () => null); |
| - break; |
| + // Set the main method. |
| + if (program.libraries.isNotEmpty) { |
| + for (Library library in results.last.kernelLibraries) { |
| + if (library.importUri == _entryPoint) { |
| + program.mainMethod = library.procedures.firstWhere( |
| + (procedure) => procedure.name.name == 'main', |
| + orElse: () => null); |
| + break; |
| + } |
| } |
| } |
| - } |
| - return new DeltaProgram(program); |
| + return new DeltaProgram(program); |
| + } finally { |
| + _isComputeDeltaExecuting = false; |
| + } |
| }); |
| } |
| @@ -153,7 +171,8 @@ class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { |
| _lastSignatures = null; |
| } |
| - /// TODO(scheglov) document |
| + /// Find files which are not referenced from the entry point and report |
| + /// them to the watch function. |
| Future<Null> _gc() async { |
| var removedFiles = _driver.fsState.gc(_entryPoint); |
| if (removedFiles.isNotEmpty && _watchFn != null) { |
| @@ -167,9 +186,11 @@ class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { |
| /// last delta - it either has not been computed yet, or has been already |
| /// accepted or rejected. |
| void _throwIfNoLastDelta() { |
| + if (_isComputeDeltaExecuting) { |
| + throw new StateError(MSG_PENDING_COMPUTE); |
| + } |
| if (_lastSignatures == null) { |
| - throw new StateError( |
| - 'The last delta has been already accepted or rejected.'); |
| + throw new StateError(MSG_NO_LAST_DELTA); |
| } |
| } |
| } |