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

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

Issue 735303002: Incremental compilation of added instance fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merged with r41904. 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
(...skipping 10 matching lines...) Expand all
21 Element, 21 Element,
22 FunctionElement, 22 FunctionElement,
23 LibraryElement, 23 LibraryElement,
24 STATE_NOT_STARTED, 24 STATE_NOT_STARTED,
25 ScopeContainerElement; 25 ScopeContainerElement;
26 26
27 import 'package:compiler/src/scanner/scannerlib.dart' show 27 import 'package:compiler/src/scanner/scannerlib.dart' show
28 EOF_TOKEN, 28 EOF_TOKEN,
29 PartialClassElement, 29 PartialClassElement,
30 PartialElement, 30 PartialElement,
31 PartialFieldList,
31 PartialFunctionElement, 32 PartialFunctionElement,
32 Token; 33 Token;
33 34
34 import 'package:compiler/src/source_file.dart' show 35 import 'package:compiler/src/source_file.dart' show
35 StringSourceFile; 36 StringSourceFile;
36 37
37 import 'package:compiler/src/tree/tree.dart' show 38 import 'package:compiler/src/tree/tree.dart' show
38 ClassNode, 39 ClassNode,
39 FunctionExpression, 40 FunctionExpression,
40 NodeList; 41 NodeList;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 final Uri uri; 110 final Uri uri;
110 111
111 final List<Update> updates = <Update>[]; 112 final List<Update> updates = <Update>[];
112 113
113 final List<FailedUpdate> _failedUpdates = <FailedUpdate>[]; 114 final List<FailedUpdate> _failedUpdates = <FailedUpdate>[];
114 115
115 final Set<ElementX> _elementsToInvalidate = new Set<ElementX>(); 116 final Set<ElementX> _elementsToInvalidate = new Set<ElementX>();
116 117
117 final Set<ElementX> _removedElements = new Set<ElementX>(); 118 final Set<ElementX> _removedElements = new Set<ElementX>();
118 119
120 final Set<ClassElementX> _classesWithSchemaChanges =
121 new Set<ClassElementX>();
122
119 LibraryUpdater( 123 LibraryUpdater(
120 this.compiler, 124 this.compiler,
121 this.inputProvider, 125 this.inputProvider,
122 this.uri, 126 this.uri,
123 this.logTime, 127 this.logTime,
124 this.logVerbose); 128 this.logVerbose);
125 129
126 /// When [true], updates must be applied (using [applyUpdates]) before the 130 /// When [true], updates must be applied (using [applyUpdates]) before the
127 /// [compiler]'s state correctly reflects the updated program. 131 /// [compiler]'s state correctly reflects the updated program.
128 bool get hasPendingUpdates => !updates.isEmpty; 132 bool get hasPendingUpdates => !updates.isEmpty;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 182
179 bool canReuseScopeContainerElement( 183 bool canReuseScopeContainerElement(
180 ScopeContainerElement element, 184 ScopeContainerElement element,
181 ScopeContainerElement newElement) { 185 ScopeContainerElement newElement) {
182 List<Difference> differences = computeDifference(element, newElement); 186 List<Difference> differences = computeDifference(element, newElement);
183 logTime('Differences computed.'); 187 logTime('Differences computed.');
184 for (Difference difference in differences) { 188 for (Difference difference in differences) {
185 logTime('Looking at difference: $difference'); 189 logTime('Looking at difference: $difference');
186 190
187 if (difference.before == null && difference.after is PartialElement) { 191 if (difference.before == null && difference.after is PartialElement) {
188 canReuseAddedElement(difference.after, element); 192 canReuseAddedElement(difference.after, element, newElement);
189 continue; 193 continue;
190 } 194 }
191 if (difference.after == null && difference.before is PartialElement) { 195 if (difference.after == null && difference.before is PartialElement) {
192 canReuseRemovedElement(difference.before); 196 canReuseRemovedElement(difference.before);
193 continue; 197 continue;
194 } 198 }
195 Token diffToken = difference.token; 199 Token diffToken = difference.token;
196 if (diffToken == null) { 200 if (diffToken == null) {
197 cannotReuse(difference, "No difference token."); 201 cannotReuse(difference, "No difference token.");
198 continue; 202 continue;
(...skipping 20 matching lines...) Expand all
219 assert(!_failedUpdates.isEmpty); 223 assert(!_failedUpdates.isEmpty);
220 continue; 224 continue;
221 } 225 }
222 } 226 }
223 227
224 return _failedUpdates.isEmpty; 228 return _failedUpdates.isEmpty;
225 } 229 }
226 230
227 bool canReuseAddedElement( 231 bool canReuseAddedElement(
228 PartialElement element, 232 PartialElement element,
229 ScopeContainerElement container) { 233 ScopeContainerElement container,
234 ScopeContainerElement syntheticContainer) {
230 if (element is PartialFunctionElement) { 235 if (element is PartialFunctionElement) {
231 addFunction(element, container); 236 addFunction(element, container);
232 return true; 237 return true;
233 } else if (element is PartialClassElement) { 238 } else if (element is PartialClassElement) {
234 addClass(element, container); 239 addClass(element, container);
235 return true; 240 return true;
241 } else if (element is PartialFieldList) {
242 addFields(element, container, syntheticContainer);
243 return true;
236 } 244 }
237 return cannotReuse(element, "Added element that isn't a function."); 245 return cannotReuse(element, "Adding ${element.runtimeType} not supported.");
238 } 246 }
239 247
240 void addFunction( 248 void addFunction(
241 PartialFunctionElement element, 249 PartialFunctionElement element,
242 /* ScopeContainerElement */ container) { 250 /* ScopeContainerElement */ container) {
243 invalidateScopesAffectedBy(element, container); 251 invalidateScopesAffectedBy(element, container);
244 252
245 updates.add(new AddedFunctionUpdate(compiler, element, container)); 253 updates.add(new AddedFunctionUpdate(compiler, element, container));
246 } 254 }
247 255
248 void addClass( 256 void addClass(
249 PartialClassElement element, 257 PartialClassElement element,
250 LibraryElementX library) { 258 LibraryElementX library) {
251 invalidateScopesAffectedBy(element, library); 259 invalidateScopesAffectedBy(element, library);
252 260
253 updates.add(new AddedClassUpdate(compiler, element, library)); 261 updates.add(new AddedClassUpdate(compiler, element, library));
254 } 262 }
255 263
264 /// Called when a field in [definition] has changed.
265 ///
266 /// There's no direct link from a [PartialFieldList] to its implied
267 /// [FieldElementX], so instead we use [syntheticContainer], the (synthetic)
268 /// container created by [canReuseLibrary], or [canReuseClass] (through
269 /// [PartialClassElement.parseNode]). This container is scanned looking for
270 /// fields whose declaration site is [definition].
271 // TODO(ahe): It would be nice if [computeDifference] returned this
272 // information directly.
273 void addFields(
274 PartialFieldList definition,
275 ScopeContainerElement container,
276 ScopeContainerElement syntheticContainer) {
277 List<FieldElementX> fields = <FieldElementX>[];
278 syntheticContainer.forEachLocalMember((ElementX member) {
279 if (member.declarationSite == definition) {
280 fields.add(member);
281 }
282 });
283 for (FieldElementX field in fields) {
284 addField(field, container);
285 }
286 }
287
288 void addField(FieldElementX element, ScopeContainerElement container) {
289 invalidateScopesAffectedBy(element, container);
290 if (!element.isInstanceMember) {
291 cannotReuse(element, "Not an instance field.");
292 } else {
293 addInstanceField(element, container);
294 }
295 }
296
297 void addInstanceField(FieldElementX element, ClassElementX cls) {
298 _classesWithSchemaChanges.add(cls);
299
300 updates.add(new AddedFieldUpdate(compiler, element, cls));
301 }
302
256 bool canReuseRemovedElement(PartialElement element) { 303 bool canReuseRemovedElement(PartialElement element) {
257 if (element is PartialFunctionElement) { 304 if (element is PartialFunctionElement) {
258 removeFunction(element); 305 removeFunction(element);
259 return true; 306 return true;
260 } else if (element is PartialClassElement) { 307 } else if (element is PartialClassElement) {
261 removeClass(element); 308 removeClass(element);
262 return true; 309 return true;
263 } 310 }
264 return cannotReuse(element, "Removed element that isn't a function."); 311 return cannotReuse(element, "Removed element that isn't a function.");
265 } 312 }
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 element.ensureResolved(compiler); 503 element.ensureResolved(compiler);
457 } 504 }
458 } 505 }
459 compiler.processQueue(compiler.enqueuer.resolution, null); 506 compiler.processQueue(compiler.enqueuer.resolution, null);
460 507
461 compiler.phase = Compiler.PHASE_DONE_RESOLVING; 508 compiler.phase = Compiler.PHASE_DONE_RESOLVING;
462 509
463 // TODO(ahe): Clean this up. Don't call this method in analyze-only mode. 510 // TODO(ahe): Clean this up. Don't call this method in analyze-only mode.
464 if (compiler.analyzeOnly) return "/* analyze only */"; 511 if (compiler.analyzeOnly) return "/* analyze only */";
465 512
466 Set<PartialClassElement> changedClasses = new Set<PartialClassElement>(); 513 Set<PartialClassElement> changedClasses =
514 new Set<PartialClassElement>.from(_classesWithSchemaChanges);
467 for (Element element in updatedElements) { 515 for (Element element in updatedElements) {
468 if (!element.isClass) { 516 if (!element.isClass) {
469 compiler.enqueuer.codegen.addToWorkList(element); 517 compiler.enqueuer.codegen.addToWorkList(element);
470 } else { 518 } else {
471 changedClasses.add(element); 519 changedClasses.add(element);
472 } 520 }
473 } 521 }
474 compiler.processQueue(compiler.enqueuer.codegen, null); 522 compiler.processQueue(compiler.enqueuer.codegen, null);
475 523
476 List<jsAst.Statement> updates = <jsAst.Statement>[]; 524 List<jsAst.Statement> updates = <jsAst.Statement>[];
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 928
881 PartialClassElement apply() { 929 PartialClassElement apply() {
882 // TODO(ahe): Reuse compilation unit of element instead? 930 // TODO(ahe): Reuse compilation unit of element instead?
883 CompilationUnitElementX compilationUnit = library.compilationUnit; 931 CompilationUnitElementX compilationUnit = library.compilationUnit;
884 PartialClassElement copy = element.copyWithEnclosing(compilationUnit); 932 PartialClassElement copy = element.copyWithEnclosing(compilationUnit);
885 compilationUnit.addMember(copy, compiler); 933 compilationUnit.addMember(copy, compiler);
886 return copy; 934 return copy;
887 } 935 }
888 } 936 }
889 937
938 class AddedFieldUpdate extends Update with JsFeatures {
939 final FieldElementX element;
940
941 final ScopeContainerElement container;
942
943 AddedFieldUpdate(Compiler compiler, this.element, this.container)
944 : super(compiler);
945
946 PartialFieldList get before => null;
947
948 PartialFieldList get after => element.declarationSite;
949
950 FieldElementX apply() {
951 FieldElementX copy = element.copyWithEnclosing(container);
952 container.addMember(copy, compiler);
953 return copy;
954 }
955 }
956
957
890 class ClassUpdate extends Update with JsFeatures { 958 class ClassUpdate extends Update with JsFeatures {
891 final PartialClassElement before; 959 final PartialClassElement before;
892 960
893 final PartialClassElement after; 961 final PartialClassElement after;
894 962
895 ClassUpdate(Compiler compiler, this.before, this.after) 963 ClassUpdate(Compiler compiler, this.before, this.after)
896 : super(compiler); 964 : super(compiler);
897 965
898 PartialFunctionElement apply() { 966 PartialFunctionElement apply() {
899 patchElement(); 967 patchElement();
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 1082
1015 ClassEmitter get classEmitter => backend.emitter.oldEmitter.classEmitter; 1083 ClassEmitter get classEmitter => backend.emitter.oldEmitter.classEmitter;
1016 1084
1017 List<String> computeFields(ClassElement cls) { 1085 List<String> computeFields(ClassElement cls) {
1018 // TODO(ahe): Rewrite for new emitter. 1086 // TODO(ahe): Rewrite for new emitter.
1019 ClassBuilder builder = new ClassBuilder(cls, namer); 1087 ClassBuilder builder = new ClassBuilder(cls, namer);
1020 classEmitter.emitFields(cls, builder, ""); 1088 classEmitter.emitFields(cls, builder, "");
1021 return builder.fields; 1089 return builder.fields;
1022 } 1090 }
1023 } 1091 }
OLDNEW
« no previous file with comments | « dart/pkg/compiler/lib/src/elements/modelx.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