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

Side by Side Diff: pkg/compiler/lib/src/enqueue.dart

Issue 2314703002: Split World usage into open, inference, and closed world. (Closed)
Patch Set: Updated cf. comments Created 4 years, 3 months 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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.enqueue; 5 library dart2js.enqueue;
6 6
7 import 'dart:collection' show Queue; 7 import 'dart:collection' show Queue;
8 8
9 import 'common/names.dart' show Identifiers; 9 import 'common/names.dart' show Identifiers;
10 import 'common/resolution.dart' show Resolution; 10 import 'common/resolution.dart' show Resolution;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 220
221 if (member.isField) { 221 if (member.isField) {
222 // The obvious thing to test here would be "member.isNative", 222 // The obvious thing to test here would be "member.isNative",
223 // however, that only works after metadata has been parsed/analyzed, 223 // however, that only works after metadata has been parsed/analyzed,
224 // and that may not have happened yet. 224 // and that may not have happened yet.
225 // So instead we use the enclosing class, which we know have had 225 // So instead we use the enclosing class, which we know have had
226 // its metadata parsed and analyzed. 226 // its metadata parsed and analyzed.
227 // Note: this assumes that there are no non-native fields on native 227 // Note: this assumes that there are no non-native fields on native
228 // classes, which may not be the case when a native class is subclassed. 228 // classes, which may not be the case when a native class is subclassed.
229 if (compiler.backend.isNative(cls)) { 229 if (compiler.backend.isNative(cls)) {
230 compiler.world.registerUsedElement(member); 230 compiler.openWorld.registerUsedElement(member);
231 if (universe.hasInvokedGetter(member, compiler.world) || 231 if (universe.hasInvokedGetter(member, compiler.openWorld) ||
232 universe.hasInvocation(member, compiler.world)) { 232 universe.hasInvocation(member, compiler.openWorld)) {
233 addToWorkList(member); 233 addToWorkList(member);
234 return; 234 return;
235 } 235 }
236 if (universe.hasInvokedSetter(member, compiler.world)) { 236 if (universe.hasInvokedSetter(member, compiler.openWorld)) {
237 addToWorkList(member); 237 addToWorkList(member);
238 return; 238 return;
239 } 239 }
240 // Native fields need to go into instanceMembersByName as they 240 // Native fields need to go into instanceMembersByName as they
241 // are virtual instantiation points and escape points. 241 // are virtual instantiation points and escape points.
242 } else { 242 } else {
243 // All field initializers must be resolved as they could 243 // All field initializers must be resolved as they could
244 // have an observable side-effect (and cannot be tree-shaken 244 // have an observable side-effect (and cannot be tree-shaken
245 // away). 245 // away).
246 addToWorkList(member); 246 addToWorkList(member);
247 return; 247 return;
248 } 248 }
249 } else if (member.isFunction) { 249 } else if (member.isFunction) {
250 FunctionElement function = member; 250 FunctionElement function = member;
251 function.computeType(resolution); 251 function.computeType(resolution);
252 if (function.name == Identifiers.noSuchMethod_) { 252 if (function.name == Identifiers.noSuchMethod_) {
253 registerNoSuchMethod(function); 253 registerNoSuchMethod(function);
254 } 254 }
255 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { 255 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) {
256 registerCallMethodWithFreeTypeVariables(function); 256 registerCallMethodWithFreeTypeVariables(function);
257 } 257 }
258 // If there is a property access with the same name as a method we 258 // If there is a property access with the same name as a method we
259 // need to emit the method. 259 // need to emit the method.
260 if (universe.hasInvokedGetter(function, compiler.world)) { 260 if (universe.hasInvokedGetter(function, compiler.openWorld)) {
261 registerClosurizedMember(function); 261 registerClosurizedMember(function);
262 addToWorkList(function); 262 addToWorkList(function);
263 return; 263 return;
264 } 264 }
265 // Store the member in [instanceFunctionsByName] to catch 265 // Store the member in [instanceFunctionsByName] to catch
266 // getters on the function. 266 // getters on the function.
267 instanceFunctionsByName 267 instanceFunctionsByName
268 .putIfAbsent(memberName, () => new Set<Element>()) 268 .putIfAbsent(memberName, () => new Set<Element>())
269 .add(member); 269 .add(member);
270 if (universe.hasInvocation(function, compiler.world)) { 270 if (universe.hasInvocation(function, compiler.openWorld)) {
271 addToWorkList(function); 271 addToWorkList(function);
272 return; 272 return;
273 } 273 }
274 } else if (member.isGetter) { 274 } else if (member.isGetter) {
275 FunctionElement getter = member; 275 FunctionElement getter = member;
276 getter.computeType(resolution); 276 getter.computeType(resolution);
277 if (universe.hasInvokedGetter(getter, compiler.world)) { 277 if (universe.hasInvokedGetter(getter, compiler.openWorld)) {
278 addToWorkList(getter); 278 addToWorkList(getter);
279 return; 279 return;
280 } 280 }
281 // We don't know what selectors the returned closure accepts. If 281 // We don't know what selectors the returned closure accepts. If
282 // the set contains any selector we have to assume that it matches. 282 // the set contains any selector we have to assume that it matches.
283 if (universe.hasInvocation(getter, compiler.world)) { 283 if (universe.hasInvocation(getter, compiler.openWorld)) {
284 addToWorkList(getter); 284 addToWorkList(getter);
285 return; 285 return;
286 } 286 }
287 } else if (member.isSetter) { 287 } else if (member.isSetter) {
288 FunctionElement setter = member; 288 FunctionElement setter = member;
289 setter.computeType(resolution); 289 setter.computeType(resolution);
290 if (universe.hasInvokedSetter(setter, compiler.world)) { 290 if (universe.hasInvokedSetter(setter, compiler.openWorld)) {
291 addToWorkList(setter); 291 addToWorkList(setter);
292 return; 292 return;
293 } 293 }
294 } 294 }
295 295
296 // The element is not yet used. Add it to the list of instance 296 // The element is not yet used. Add it to the list of instance
297 // members to still be processed. 297 // members to still be processed.
298 instanceMembersByName 298 instanceMembersByName
299 .putIfAbsent(memberName, () => new Set<Element>()) 299 .putIfAbsent(memberName, () => new Set<Element>())
300 .add(member); 300 .add(member);
301 } 301 }
302 302
303 void processInstantiatedClass(ClassElement cls) { 303 void processInstantiatedClass(ClassElement cls) {
304 task.measure(() { 304 task.measure(() {
305 if (_processedClasses.contains(cls)) return; 305 if (_processedClasses.contains(cls)) return;
306 // The class must be resolved to compute the set of all 306 // The class must be resolved to compute the set of all
307 // supertypes. 307 // supertypes.
308 cls.ensureResolved(resolution); 308 cls.ensureResolved(resolution);
309 309
310 void processClass(ClassElement superclass) { 310 void processClass(ClassElement superclass) {
311 if (_processedClasses.contains(superclass)) return; 311 if (_processedClasses.contains(superclass)) return;
312 // TODO(johnniwinther): Re-insert this invariant when unittests don't
313 // fail. There is already a similar invariant on the members.
314 /*if (!isResolutionQueue) {
315 assert(invariant(superclass,
316 superclass.isClosure ||
317 compiler.enqueuer.resolution.isClassProcessed(superclass),
318 message: "Class $superclass has not been "
319 "processed in resolution."));
320 }*/
321 312
322 _processedClasses.add(superclass); 313 _processedClasses.add(superclass);
323 recentClasses.add(superclass); 314 recentClasses.add(superclass);
324 superclass.ensureResolved(resolution); 315 superclass.ensureResolved(resolution);
325 superclass.implementation.forEachMember(processInstantiatedClassMember); 316 superclass.implementation.forEachMember(processInstantiatedClassMember);
326 if (isResolutionQueue && 317 if (!compiler.serialization.isDeserialized(superclass)) {
327 !compiler.serialization.isDeserialized(superclass)) {
328 compiler.resolver.checkClass(superclass); 318 compiler.resolver.checkClass(superclass);
329 } 319 }
330 // We only tell the backend once that [superclass] was instantiated, so 320 // We only tell the backend once that [superclass] was instantiated, so
331 // any additional dependencies must be treated as global 321 // any additional dependencies must be treated as global
332 // dependencies. 322 // dependencies.
333 compiler.backend.registerInstantiatedClass( 323 compiler.backend.registerInstantiatedClass(
334 superclass, this, compiler.globalDependencies); 324 superclass, this, compiler.globalDependencies);
335 } 325 }
336 326
337 ClassElement superclass = cls; 327 ClassElement superclass = cls;
338 while (superclass != null) { 328 while (superclass != null) {
339 processClass(superclass); 329 processClass(superclass);
340 superclass = superclass.superclass; 330 superclass = superclass.superclass;
341 } 331 }
342 }); 332 });
343 } 333 }
344 334
345 void registerDynamicUse(DynamicUse dynamicUse) { 335 void registerDynamicUse(DynamicUse dynamicUse) {
346 task.measure(() { 336 task.measure(() {
347 if (universe.registerDynamicUse(dynamicUse)) { 337 if (universe.registerDynamicUse(dynamicUse)) {
348 handleUnseenSelector(dynamicUse); 338 handleUnseenSelector(dynamicUse);
349 } 339 }
350 }); 340 });
351 } 341 }
352 342
353 void logEnqueueReflectiveAction(action, [msg = ""]) { 343 void logEnqueueReflectiveAction(action, [msg = ""]) {
354 if (TRACE_MIRROR_ENQUEUING) { 344 if (TRACE_MIRROR_ENQUEUING) {
355 print("MIRROR_ENQUEUE (${isResolutionQueue ? "R" : "C"}): $action $msg"); 345 print("MIRROR_ENQUEUE (R): $action $msg");
356 } 346 }
357 } 347 }
358 348
359 /// Enqeue the constructor [ctor] if it is required for reflection. 349 /// Enqeue the constructor [ctor] if it is required for reflection.
360 /// 350 ///
361 /// [enclosingWasIncluded] provides a hint whether the enclosing element was 351 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
362 /// needed for reflection. 352 /// needed for reflection.
363 void enqueueReflectiveConstructor( 353 void enqueueReflectiveConstructor(
364 ConstructorElement ctor, bool enclosingWasIncluded) { 354 ConstructorElement ctor, bool enclosingWasIncluded) {
365 if (shouldIncludeElementDueToMirrors(ctor, 355 if (shouldIncludeElementDueToMirrors(ctor,
(...skipping 11 matching lines...) Expand all
377 /// 367 ///
378 /// [enclosingWasIncluded] provides a hint whether the enclosing element was 368 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
379 /// needed for reflection. 369 /// needed for reflection.
380 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { 370 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) {
381 if (shouldIncludeElementDueToMirrors(element, 371 if (shouldIncludeElementDueToMirrors(element,
382 includedEnclosing: enclosingWasIncluded)) { 372 includedEnclosing: enclosingWasIncluded)) {
383 logEnqueueReflectiveAction(element); 373 logEnqueueReflectiveAction(element);
384 if (element.isTypedef) { 374 if (element.isTypedef) {
385 TypedefElement typedef = element; 375 TypedefElement typedef = element;
386 typedef.ensureResolved(resolution); 376 typedef.ensureResolved(resolution);
387 compiler.world.allTypedefs.add(element);
388 } else if (Elements.isStaticOrTopLevel(element)) { 377 } else if (Elements.isStaticOrTopLevel(element)) {
389 registerStaticUse(new StaticUse.foreignUse(element.declaration)); 378 registerStaticUse(new StaticUse.foreignUse(element.declaration));
390 } else if (element.isInstanceMember) { 379 } else if (element.isInstanceMember) {
391 // We need to enqueue all members matching this one in subclasses, as 380 // We need to enqueue all members matching this one in subclasses, as
392 // well. 381 // well.
393 // TODO(herhut): Use TypedSelector.subtype for enqueueing 382 // TODO(herhut): Use TypedSelector.subtype for enqueueing
394 DynamicUse dynamicUse = 383 DynamicUse dynamicUse =
395 new DynamicUse(new Selector.fromElement(element), null); 384 new DynamicUse(new Selector.fromElement(element), null);
396 registerDynamicUse(dynamicUse); 385 registerDynamicUse(dynamicUse);
397 if (element.isField) { 386 if (element.isField) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 } 530 }
542 531
543 void handleUnseenSelector(DynamicUse universeSelector) { 532 void handleUnseenSelector(DynamicUse universeSelector) {
544 strategy.processDynamicUse(this, universeSelector); 533 strategy.processDynamicUse(this, universeSelector);
545 } 534 }
546 535
547 void handleUnseenSelectorInternal(DynamicUse dynamicUse) { 536 void handleUnseenSelectorInternal(DynamicUse dynamicUse) {
548 Selector selector = dynamicUse.selector; 537 Selector selector = dynamicUse.selector;
549 String methodName = selector.name; 538 String methodName = selector.name;
550 processInstanceMembers(methodName, (Element member) { 539 processInstanceMembers(methodName, (Element member) {
551 if (dynamicUse.appliesUnnamed(member, compiler.world)) { 540 if (dynamicUse.appliesUnnamed(member, compiler.openWorld)) {
552 if (member.isFunction && selector.isGetter) { 541 if (member.isFunction && selector.isGetter) {
553 registerClosurizedMember(member); 542 registerClosurizedMember(member);
554 } 543 }
555 addToWorkList(member); 544 addToWorkList(member);
556 return true; 545 return true;
557 } 546 }
558 return false; 547 return false;
559 }); 548 });
560 if (selector.isGetter) { 549 if (selector.isGetter) {
561 processInstanceFunctions(methodName, (Element member) { 550 processInstanceFunctions(methodName, (Element member) {
562 if (dynamicUse.appliesUnnamed(member, compiler.world)) { 551 if (dynamicUse.appliesUnnamed(member, compiler.openWorld)) {
563 registerClosurizedMember(member); 552 registerClosurizedMember(member);
564 return true; 553 return true;
565 } 554 }
566 return false; 555 return false;
567 }); 556 });
568 } 557 }
569 } 558 }
570 559
571 /** 560 /**
572 * Documentation wanted -- johnniwinther 561 * Documentation wanted -- johnniwinther
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 if (element.isMalformed) return false; 715 if (element.isMalformed) return false;
727 716
728 assert(invariant(element, element is AnalyzableElement, 717 assert(invariant(element, element is AnalyzableElement,
729 message: 'Element $element is not analyzable.')); 718 message: 'Element $element is not analyzable.'));
730 if (hasBeenProcessed(element)) return false; 719 if (hasBeenProcessed(element)) return false;
731 if (queueIsClosed) { 720 if (queueIsClosed) {
732 throw new SpannableAssertionFailure( 721 throw new SpannableAssertionFailure(
733 element, "Resolution work list is closed. Trying to add $element."); 722 element, "Resolution work list is closed. Trying to add $element.");
734 } 723 }
735 724
736 compiler.world.registerUsedElement(element); 725 compiler.openWorld.registerUsedElement(element);
737 726
738 ResolutionWorkItem workItem = compiler.resolution.createWorkItem(element); 727 ResolutionWorkItem workItem = compiler.resolution.createWorkItem(element);
739 queue.add(workItem); 728 queue.add(workItem);
740 729
741 // Enable isolate support if we start using something from the isolate 730 // Enable isolate support if we start using something from the isolate
742 // library, or timers for the async library. We exclude constant fields, 731 // library, or timers for the async library. We exclude constant fields,
743 // which are ending here because their initializing expression is compiled. 732 // which are ending here because their initializing expression is compiled.
744 LibraryElement library = element.library; 733 LibraryElement library = element.library;
745 if (!compiler.hasIsolateSupport && (!element.isField || !element.isConst)) { 734 if (!compiler.hasIsolateSupport && (!element.isField || !element.isConst)) {
746 String uri = library.canonicalUri.toString(); 735 String uri = library.canonicalUri.toString();
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 } 901 }
913 902
914 typedef void _DeferredActionFunction(); 903 typedef void _DeferredActionFunction();
915 904
916 class _DeferredAction { 905 class _DeferredAction {
917 final Element element; 906 final Element element;
918 final _DeferredActionFunction action; 907 final _DeferredActionFunction action;
919 908
920 _DeferredAction(this.element, this.action); 909 _DeferredAction(this.element, this.action);
921 } 910 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/elements/elements.dart ('k') | pkg/compiler/lib/src/inferrer/inferrer_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698