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

Side by Side Diff: dart/pkg/dart2js_incremental/lib/library_updater.dart

Issue 796353003: Incremental compiler detects when library graph changes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merged with r42504. Created 6 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 dart2js_incremental.library_updater; 5 library dart2js_incremental.library_updater;
6 6
7 import 'dart:async' show 7 import 'dart:async' show
8 Future; 8 Future;
9 9
10 import 'dart:convert' show 10 import 'dart:convert' show
11 UTF8; 11 UTF8;
12 12
13 import 'package:compiler/compiler.dart' as api; 13 import 'package:compiler/compiler.dart' as api;
14 14
15 import 'package:compiler/src/dart2jslib.dart' show 15 import 'package:compiler/src/dart2jslib.dart' show
16 Compiler, 16 Compiler,
17 EnqueueTask, 17 EnqueueTask,
18 Script; 18 Script;
19 19
20 import 'package:compiler/src/elements/elements.dart' show 20 import 'package:compiler/src/elements/elements.dart' show
21 ClassElement, 21 ClassElement,
22 Element, 22 Element,
23 FunctionElement, 23 FunctionElement,
24 LibraryElement, 24 LibraryElement,
25 STATE_NOT_STARTED, 25 STATE_NOT_STARTED,
26 ScopeContainerElement; 26 ScopeContainerElement;
27 27
28 import 'package:compiler/src/scanner/scannerlib.dart' show 28 import 'package:compiler/src/scanner/scannerlib.dart' show
29 EOF_TOKEN, 29 EOF_TOKEN,
30 Listener,
31 NodeListener,
32 Parser,
30 PartialClassElement, 33 PartialClassElement,
31 PartialElement, 34 PartialElement,
32 PartialFieldList, 35 PartialFieldList,
33 PartialFunctionElement, 36 PartialFunctionElement,
37 Scanner,
34 Token; 38 Token;
35 39
36 import 'package:compiler/src/source_file.dart' show 40 import 'package:compiler/src/source_file.dart' show
41 CachingUtf8BytesSourceFile,
42 SourceFile,
37 StringSourceFile; 43 StringSourceFile;
38 44
39 import 'package:compiler/src/tree/tree.dart' show 45 import 'package:compiler/src/tree/tree.dart' show
40 ClassNode, 46 ClassNode,
41 FunctionExpression, 47 FunctionExpression,
42 NodeList; 48 LibraryTag,
49 NodeList,
50 Part,
51 StringNode,
52 unparse;
43 53
44 import 'package:compiler/src/js/js.dart' show 54 import 'package:compiler/src/js/js.dart' show
45 js; 55 js;
46 56
47 import 'package:compiler/src/js/js.dart' as jsAst; 57 import 'package:compiler/src/js/js.dart' as jsAst;
48 58
49 import 'package:compiler/src/js_emitter/js_emitter.dart' show 59 import 'package:compiler/src/js_emitter/js_emitter.dart' show
50 ClassBuilder, 60 ClassBuilder,
51 ClassEmitter, 61 ClassEmitter,
52 CodeEmitterTask, 62 CodeEmitterTask,
(...skipping 24 matching lines...) Expand all
77 Selector; 87 Selector;
78 88
79 import 'package:compiler/src/constants/values.dart' show 89 import 'package:compiler/src/constants/values.dart' show
80 ConstantValue; 90 ConstantValue;
81 91
82 import 'diff.dart' show 92 import 'diff.dart' show
83 Difference, 93 Difference,
84 computeDifference; 94 computeDifference;
85 95
86 import 'dart2js_incremental.dart' show 96 import 'dart2js_incremental.dart' show
97 IncrementalCompilationFailed,
87 IncrementalCompiler; 98 IncrementalCompiler;
88 99
89 typedef void Logger(message); 100 typedef void Logger(message);
90 101
91 typedef bool Reuser( 102 typedef bool Reuser(
92 Token diffToken, 103 Token diffToken,
93 PartialElement before, 104 PartialElement before,
94 PartialElement after); 105 PartialElement after);
95 106
96 class FailedUpdate { 107 class FailedUpdate {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 172
162 final Set<ElementX> _elementsToInvalidate = new Set<ElementX>(); 173 final Set<ElementX> _elementsToInvalidate = new Set<ElementX>();
163 174
164 final Set<ElementX> _removedElements = new Set<ElementX>(); 175 final Set<ElementX> _removedElements = new Set<ElementX>();
165 176
166 final Set<ClassElementX> _classesWithSchemaChanges = 177 final Set<ClassElementX> _classesWithSchemaChanges =
167 new Set<ClassElementX>(); 178 new Set<ClassElementX>();
168 179
169 final IncrementalCompilerContext _context; 180 final IncrementalCompilerContext _context;
170 181
182 final Map<Uri, Future> _sources = <Uri, Future>{};
183
171 bool _hasComputedNeeds = false; 184 bool _hasComputedNeeds = false;
172 185
173 bool _hasCapturedCompilerState = false; 186 bool _hasCapturedCompilerState = false;
174 187
175 LibraryUpdater( 188 LibraryUpdater(
176 this.compiler, 189 this.compiler,
177 this.inputProvider, 190 this.inputProvider,
178 this.logTime, 191 this.logTime,
179 this.logVerbose, 192 this.logVerbose,
180 this._context) { 193 this._context) {
(...skipping 24 matching lines...) Expand all
205 bool get failed => !_failedUpdates.isEmpty; 218 bool get failed => !_failedUpdates.isEmpty;
206 219
207 /// Used as tear-off passed to [LibraryLoaderTask.resetAsync]. 220 /// Used as tear-off passed to [LibraryLoaderTask.resetAsync].
208 Future<bool> reuseLibrary(LibraryElement library) { 221 Future<bool> reuseLibrary(LibraryElement library) {
209 _ensureCompilerStateCaptured(); 222 _ensureCompilerStateCaptured();
210 assert(compiler != null); 223 assert(compiler != null);
211 if (library.isPlatformLibrary) { 224 if (library.isPlatformLibrary) {
212 logTime('Reusing $library (assumed read-only).'); 225 logTime('Reusing $library (assumed read-only).');
213 return new Future.value(true); 226 return new Future.value(true);
214 } 227 }
215 for (CompilationUnitElementX unit in library.compilationUnits) { 228 return _haveTagsChanged(library).then((bool haveTagsChanged) {
216 Uri uri = unit.script.resourceUri; 229 if (haveTagsChanged) {
217 if (_context._uriHasUpdate(uri)) { 230 cannotReuse(
218 if (!library.compilationUnits.tail.isEmpty) { 231 library,
219 // TODO(ahe): Remove this restriction. 232 "Changes to library, import, export, or part declarations not"
220 cannotReuse(library, "Multiple compilation units not supported."); 233 " supported.");
221 return new Future.value(true); 234 return true;
235 }
236 for (CompilationUnitElementX unit in library.compilationUnits) {
237 Uri uri = unit.script.resourceUri;
238 if (_context._uriHasUpdate(uri)) {
239 if (!library.compilationUnits.tail.isEmpty) {
240 // TODO(ahe): Remove this restriction.
241 cannotReuse(
242 library,
243 "Multiple compilation units not supported"
244 " (${library.compilationUnits}).");
245 return true;
246 }
247 return _readUri(uri).then((bytes) {
248 return canReuseLibrary(library, bytes);
249 });
222 } 250 }
223 return inputProvider(uri).then((bytes) {
224 return canReuseLibrary(library, bytes);
225 });
226 } 251 }
252
253 logTime("Reusing $library, source didn't change.");
254 // Source code of [library] wasn't changed.
255 return true;
256 });
257 }
258
259 Future<bool> _haveTagsChanged(LibraryElement library) {
260 Uri uri = library.entryCompilationUnit.script.resourceUri;
261 if (!_context._uriHasUpdate(uri)) {
262 // The entry compilation unit hasn't been updated. So the tags aren't
263 // changed.
264 return new Future<bool>.value(false);
227 } 265 }
228 266
229 logTime("Reusing $library, source didn't change."); 267 return _readUri(uri).then((bytes) {
230 // Source code of [library] wasn't changed. 268 String filename = '$uri';
231 return new Future.value(true); 269 SourceFile sourceFile = bytes is String
270 ? new StringSourceFile(filename, bytes)
271 : new CachingUtf8BytesSourceFile(filename, bytes);
272 Token token = new Scanner(sourceFile).tokenize();
273 // Using two parsers to only create the nodes we want ([LibraryTag]).
274 Parser parser = new Parser(new Listener());
275 NodeListener listener = new NodeListener(
276 compiler, library.entryCompilationUnit);
277 Parser nodeParser = new Parser(listener);
278 Iterator<LibraryTag> tags = library.tags.iterator;
279 while (token.kind != EOF_TOKEN) {
280 token = parser.parseMetadataStar(token);
281 if (parser.optional('library', token) ||
282 parser.optional('import', token) ||
283 parser.optional('export', token) ||
284 parser.optional('part', token)) {
285 if (!tags.moveNext()) return true;
286 token = nodeParser.parseTopLevelDeclaration(token);
287 LibraryTag tag = listener.popNode();
288 assert(listener.nodes.isEmpty);
289 if (unparse(tags.current) != unparse(tag)) {
290 return true;
291 }
292 } else {
293 break;
294 }
295 }
296 return tags.moveNext();
297 });
298 }
299
300 Future _readUri(Uri uri) {
301 return _sources.putIfAbsent(uri, () => inputProvider(uri));
232 } 302 }
233 303
234 void _ensureCompilerStateCaptured() { 304 void _ensureCompilerStateCaptured() {
235 // TODO(ahe): [compiler] shouldn't be null, remove the following line. 305 // TODO(ahe): [compiler] shouldn't be null, remove the following line.
236 if (compiler == null) return; 306 if (compiler == null) return;
237 307
238 if (_hasCapturedCompilerState) return; 308 if (_hasCapturedCompilerState) return;
239 _context._captureState(compiler); 309 _context._captureState(compiler);
240 _hasCapturedCompilerState = true; 310 _hasCapturedCompilerState = true;
241 } 311 }
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 } 646 }
577 647
578 /// Apply the collected [updates]. Return a list of elements that needs to be 648 /// Apply the collected [updates]. Return a list of elements that needs to be
579 /// recompiled after applying the updates. Any elements removed as a 649 /// recompiled after applying the updates. Any elements removed as a
580 /// consequence of applying the patches are added to [removals] if provided. 650 /// consequence of applying the patches are added to [removals] if provided.
581 List<Element> applyUpdates([List<Update> removals]) { 651 List<Element> applyUpdates([List<Update> removals]) {
582 for (Update update in updates) { 652 for (Update update in updates) {
583 update.captureState(); 653 update.captureState();
584 } 654 }
585 if (!_failedUpdates.isEmpty) { 655 if (!_failedUpdates.isEmpty) {
586 throw new StateError( 656 throw new IncrementalCompilationFailed(_failedUpdates.join('\n\n'));
587 "Can't compute update.\n\n${_failedUpdates.join('\n\n')}");
588 } 657 }
589 for (ElementX element in _elementsToInvalidate) { 658 for (ElementX element in _elementsToInvalidate) {
590 compiler.forgetElement(element); 659 compiler.forgetElement(element);
591 element.reuseElement(); 660 element.reuseElement();
592 } 661 }
593 List<Element> elementsToInvalidate = <Element>[]; 662 List<Element> elementsToInvalidate = <Element>[];
594 for (ElementX element in _elementsToInvalidate) { 663 for (ElementX element in _elementsToInvalidate) {
595 if (!_removedElements.contains(element)) { 664 if (!_removedElements.contains(element)) {
596 elementsToInvalidate.add(element); 665 elementsToInvalidate.add(element);
597 } 666 }
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 List<String> computeFields(ClassElement cls) { 1402 List<String> computeFields(ClassElement cls) {
1334 // TODO(ahe): Rewrite for new emitter. 1403 // TODO(ahe): Rewrite for new emitter.
1335 ClassBuilder builder = new ClassBuilder(cls, namer); 1404 ClassBuilder builder = new ClassBuilder(cls, namer);
1336 classEmitter.emitFields(cls, builder); 1405 classEmitter.emitFields(cls, builder);
1337 return builder.fields; 1406 return builder.fields;
1338 } 1407 }
1339 } 1408 }
1340 1409
1341 // TODO(ahe): Remove this method. 1410 // TODO(ahe): Remove this method.
1342 NO_WARN(x) => x; 1411 NO_WARN(x) => x;
OLDNEW
« no previous file with comments | « dart/pkg/dart2js_incremental/lib/dart2js_incremental.dart ('k') | dart/tests/try/web/incremental_compilation_update_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698