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 import 'dart:io'; | 6 import 'dart:io'; |
7 | 7 |
8 import 'package:front_end/file_system.dart'; | 8 import 'package:front_end/file_system.dart'; |
9 import 'package:front_end/incremental_kernel_generator.dart'; | 9 import 'package:front_end/incremental_kernel_generator.dart'; |
10 import 'package:front_end/incremental_resolved_ast_generator.dart'; | 10 import 'package:front_end/incremental_resolved_ast_generator.dart'; |
(...skipping 27 matching lines...) Expand all Loading... |
38 } | 38 } |
39 | 39 |
40 /// Implementation of [IncrementalKernelGenerator]. | 40 /// Implementation of [IncrementalKernelGenerator]. |
41 /// | 41 /// |
42 /// TODO(scheglov) Update the documentation. | 42 /// TODO(scheglov) Update the documentation. |
43 /// | 43 /// |
44 /// Theory of operation: an instance of [IncrementalResolvedAstGenerator] is | 44 /// Theory of operation: an instance of [IncrementalResolvedAstGenerator] is |
45 /// used to obtain resolved ASTs, and these are fed into kernel code generation | 45 /// used to obtain resolved ASTs, and these are fed into kernel code generation |
46 /// logic. | 46 /// logic. |
47 class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { | 47 class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { |
| 48 /// The version of data format, should be incremented on every format change. |
| 49 static const int DATA_VERSION = 1; |
| 50 |
48 /// The compiler options, such as the [FileSystem], the SDK dill location, | 51 /// The compiler options, such as the [FileSystem], the SDK dill location, |
49 /// etc. | 52 /// etc. |
50 final ProcessedOptions _options; | 53 final ProcessedOptions _options; |
51 | 54 |
52 /// The object that knows how to resolve "package:" and "dart:" URIs. | 55 /// The object that knows how to resolve "package:" and "dart:" URIs. |
53 final TranslateUri _uriTranslator; | 56 final TranslateUri _uriTranslator; |
54 | 57 |
55 /// The logger to report compilation progress. | 58 /// The logger to report compilation progress. |
56 final PerformanceLog _logger; | 59 final PerformanceLog _logger; |
57 | 60 |
58 /// The current file system state. | 61 /// The current file system state. |
59 final FileSystemState _fsState; | 62 final FileSystemState _fsState; |
60 | 63 |
61 /// The byte storage to get and put serialized data. | 64 /// The byte storage to get and put serialized data. |
62 final ByteStore _byteStore; | 65 final ByteStore _byteStore; |
63 | 66 |
64 /// The URI of the program entry point. | 67 /// The URI of the program entry point. |
65 final Uri _entryPoint; | 68 final Uri _entryPoint; |
66 | 69 |
| 70 /// The salt to mix into all hashes used as keys for serialized data. |
| 71 List<int> _salt; |
| 72 |
67 /// Latest compilation signatures produced by [computeDelta] for libraries. | 73 /// Latest compilation signatures produced by [computeDelta] for libraries. |
68 final Map<Uri, String> _uriToLatestSignature = {}; | 74 final Map<Uri, String> _latestSignature = {}; |
69 | 75 |
70 /// The set of absolute file URIs that were reported through [invalidate] | 76 /// The set of absolute file URIs that were reported through [invalidate] |
71 /// and not checked for actual changes yet. | 77 /// and not checked for actual changes yet. |
72 final Set<Uri> _invalidatedFiles = new Set<Uri>(); | 78 final Set<Uri> _invalidatedFiles = new Set<Uri>(); |
73 | 79 |
74 IncrementalKernelGeneratorImpl( | 80 IncrementalKernelGeneratorImpl( |
75 this._options, this._uriTranslator, this._entryPoint) | 81 this._options, this._uriTranslator, this._entryPoint) |
76 : _logger = _options.logger, | 82 : _logger = _options.logger, |
77 _fsState = new FileSystemState(_options.fileSystem, _uriTranslator), | 83 _fsState = new FileSystemState(_options.fileSystem, _uriTranslator), |
78 _byteStore = _options.byteStore; | 84 _byteStore = _options.byteStore { |
| 85 _computeSalt(); |
| 86 } |
79 | 87 |
80 @override | 88 @override |
81 Future<DeltaProgram> computeDelta( | 89 Future<DeltaProgram> computeDelta( |
82 {Future<Null> watch(Uri uri, bool used)}) async { | 90 {Future<Null> watch(Uri uri, bool used)}) async { |
83 return await _logger.runAsync('Compute delta', () async { | 91 return await _logger.runAsync('Compute delta', () async { |
84 await _refreshInvalidatedFiles(); | 92 await _refreshInvalidatedFiles(); |
85 | 93 |
86 // Ensure that the graph starting at the entry point is ready. | 94 // Ensure that the graph starting at the entry point is ready. |
87 FileState entryLibrary = await _fsState.getFile(_entryPoint); | 95 FileState entryLibrary = await _fsState.getFile(_entryPoint); |
88 | 96 |
(...skipping 15 matching lines...) Expand all Loading... |
104 results.add(result); | 112 results.add(result); |
105 } | 113 } |
106 }); | 114 }); |
107 | 115 |
108 Program program = new Program(nameRoot: nameRoot); | 116 Program program = new Program(nameRoot: nameRoot); |
109 | 117 |
110 // Add affected libraries (with different signatures). | 118 // Add affected libraries (with different signatures). |
111 for (_LibraryCycleResult result in results) { | 119 for (_LibraryCycleResult result in results) { |
112 for (Library library in result.kernelLibraries) { | 120 for (Library library in result.kernelLibraries) { |
113 Uri uri = library.importUri; | 121 Uri uri = library.importUri; |
114 if (_uriToLatestSignature[uri] != result.signature) { | 122 if (_latestSignature[uri] != result.signature) { |
115 _uriToLatestSignature[uri] = result.signature; | 123 _latestSignature[uri] = result.signature; |
116 program.libraries.add(library); | 124 program.libraries.add(library); |
117 } | 125 } |
118 } | 126 } |
119 } | 127 } |
120 | 128 |
121 // TODO(scheglov) Add libraries which import changed libraries. | 129 // TODO(scheglov) Add libraries which import changed libraries. |
122 | 130 |
123 return new DeltaProgram(program); | 131 return new DeltaProgram(program); |
124 }); | 132 }); |
125 } | 133 } |
126 | 134 |
127 @override | 135 @override |
128 void invalidate(Uri uri) { | 136 void invalidate(Uri uri) { |
129 _invalidatedFiles.add(uri); | 137 _invalidatedFiles.add(uri); |
130 } | 138 } |
131 | 139 |
132 @override | 140 @override |
133 void invalidateAll() => unimplemented(); | 141 void invalidateAll() => unimplemented(); |
134 | 142 |
135 /// Ensure that [dillTarget] includes the [cycle] libraries. It already | 143 /// Ensure that [dillTarget] includes the [cycle] libraries. It already |
136 /// contains all the libraries that sorted before the given [cycle] in | 144 /// contains all the libraries that sorted before the given [cycle] in |
137 /// topological order. Return the result with the cycle libraries. | 145 /// topological order. Return the result with the cycle libraries. |
138 Future<_LibraryCycleResult> _compileCycle( | 146 Future<_LibraryCycleResult> _compileCycle( |
139 CanonicalName nameRoot, DillTarget dillTarget, LibraryCycle cycle) async { | 147 CanonicalName nameRoot, DillTarget dillTarget, LibraryCycle cycle) async { |
140 return _logger.runAsync('Compile cycle $cycle', () async { | 148 return _logger.runAsync('Compile cycle $cycle', () async { |
141 String signature; | 149 String signature; |
142 { | 150 { |
143 var signatureBuilder = new ApiSignature(); | 151 var signatureBuilder = new ApiSignature(); |
144 // TODO(scheglov) add salt | 152 signatureBuilder.addBytes(_salt); |
145 // signature.addUint32List(_fsState._salt); | |
146 Set<FileState> transitiveFiles = cycle.libraries | 153 Set<FileState> transitiveFiles = cycle.libraries |
147 .map((library) => library.transitiveFiles) | 154 .map((library) => library.transitiveFiles) |
148 .expand((files) => files) | 155 .expand((files) => files) |
149 .toSet(); | 156 .toSet(); |
150 signatureBuilder.addInt(transitiveFiles.length); | 157 signatureBuilder.addInt(transitiveFiles.length); |
151 for (var file in transitiveFiles) { | 158 for (var file in transitiveFiles) { |
152 signatureBuilder.addString(file.uri.toString()); | 159 signatureBuilder.addString(file.uri.toString()); |
153 // TODO(scheglov) use API signature | 160 // TODO(scheglov) use API signature |
154 signatureBuilder.addBytes(file.contentHash); | 161 signatureBuilder.addBytes(file.contentHash); |
155 } | 162 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 } | 253 } |
247 }); | 254 }); |
248 } else { | 255 } else { |
249 // TODO(scheglov) How to handle this? | 256 // TODO(scheglov) How to handle this? |
250 } | 257 } |
251 } | 258 } |
252 } | 259 } |
253 } while (wasChanged); | 260 } while (wasChanged); |
254 } | 261 } |
255 | 262 |
| 263 /// Compute salt and put into [_salt]. |
| 264 void _computeSalt() { |
| 265 var saltBuilder = new ApiSignature(); |
| 266 saltBuilder.addInt(DATA_VERSION); |
| 267 saltBuilder.addBool(_options.strongMode); |
| 268 saltBuilder.addString(_entryPoint.toString()); |
| 269 _salt = saltBuilder.toByteList(); |
| 270 } |
| 271 |
256 /// Refresh all the invalidated files and update dependencies. | 272 /// Refresh all the invalidated files and update dependencies. |
257 Future<Null> _refreshInvalidatedFiles() async { | 273 Future<Null> _refreshInvalidatedFiles() async { |
258 await _logger.runAsync('Refresh invalidated files', () async { | 274 await _logger.runAsync('Refresh invalidated files', () async { |
259 for (var fileUri in _invalidatedFiles) { | 275 for (var fileUri in _invalidatedFiles) { |
260 var file = await _fsState.getFile(fileUri); | 276 var file = await _fsState.getFile(fileUri); |
261 await file.refresh(); | 277 await file.refresh(); |
262 } | 278 } |
263 _invalidatedFiles.clear(); | 279 _invalidatedFiles.clear(); |
264 }); | 280 }); |
265 } | 281 } |
(...skipping 18 matching lines...) Expand all Loading... |
284 /// TODO(scheglov) Use API signatures. | 300 /// TODO(scheglov) Use API signatures. |
285 /// TODO(scheglov) Or use tree shaking and compute signatures of outlines. | 301 /// TODO(scheglov) Or use tree shaking and compute signatures of outlines. |
286 final String signature; | 302 final String signature; |
287 | 303 |
288 /// Kernel libraries for libraries in the [cycle]. Bodies of dependencies | 304 /// Kernel libraries for libraries in the [cycle]. Bodies of dependencies |
289 /// are not included, but but references to those dependencies are included. | 305 /// are not included, but but references to those dependencies are included. |
290 final List<Library> kernelLibraries; | 306 final List<Library> kernelLibraries; |
291 | 307 |
292 _LibraryCycleResult(this.cycle, this.signature, this.kernelLibraries); | 308 _LibraryCycleResult(this.cycle, this.signature, this.kernelLibraries); |
293 } | 309 } |
OLD | NEW |