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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/enqueue.dart

Issue 1259553002: Emit program and dependency information as relations in a Prolog database. Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 5 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 | Annotate | Revision Log
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 part of dart2js; 5 part of dart2js;
6 6
7 typedef ItemCompilationContext ItemCompilationContextCreator(); 7 typedef ItemCompilationContext ItemCompilationContextCreator();
8 8
9 class EnqueueTask extends CompilerTask { 9 class EnqueueTask extends CompilerTask {
10 final ResolutionEnqueuer resolution; 10 final ResolutionEnqueuer resolution;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 final Set<ClassElement> seenClasses = new Set<ClassElement>(); 75 final Set<ClassElement> seenClasses = new Set<ClassElement>();
76 final Universe universe = new Universe(); 76 final Universe universe = new Universe();
77 77
78 bool queueIsClosed = false; 78 bool queueIsClosed = false;
79 EnqueueTask task; 79 EnqueueTask task;
80 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask 80 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
81 81
82 bool hasEnqueuedEverything = false; 82 bool hasEnqueuedEverything = false;
83 bool hasEnqueuedReflectiveStaticFields = false; 83 bool hasEnqueuedReflectiveStaticFields = false;
84 84
85 Relations get dependencies;
86
85 Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator); 87 Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator);
86 88
87 Queue<WorkItem> get queue; 89 Queue<WorkItem> get queue;
88 90
89 /// Returns [:true:] if this enqueuer is the resolution enqueuer. 91 /// Returns [:true:] if this enqueuer is the resolution enqueuer.
90 bool get isResolutionQueue => false; 92 bool get isResolutionQueue => false;
91 93
92 /// Returns [:true:] if [member] has been processed by this enqueuer. 94 /// Returns [:true:] if [member] has been processed by this enqueuer.
93 bool isProcessed(Element member); 95 bool isProcessed(Element member);
94 96
95 /** 97 /**
96 * Documentation wanted -- johnniwinther 98 * Documentation wanted -- johnniwinther
97 * 99 *
98 * Invariant: [element] must be a declaration element. 100 * Invariant: [element] must be a declaration element.
99 */ 101 */
100 void addToWorkList(Element element) { 102 void addToWorkList(Element element) {
101 assert(invariant(element, element.isDeclaration)); 103 assert(invariant(element, element.isDeclaration));
102 internalAddToWorkList(element); 104 if (internalAddToWorkList(element)) {
105 dependencies.put('addsToWorklist', compiler.currentElement, element);
106 }
103 } 107 }
104 108
105 /** 109 /**
106 * Adds [element] to the work list if it has not already been processed. 110 * Adds [element] to the work list if it has not already been processed.
111 *
112 * Returns [true] if the element was actually added to the queue.
107 */ 113 */
108 void internalAddToWorkList(Element element); 114 bool internalAddToWorkList(Element element);
109 115
110 void registerInstantiatedType(InterfaceType type, Registry registry) { 116 void registerInstantiatedType(InterfaceType type, Registry registry) {
111 task.measure(() { 117 task.measure(() {
112 ClassElement cls = type.element; 118 ClassElement cls = type.element;
113 registry.registerDependency(cls); 119 registry.registerDependency(cls);
114 cls.ensureResolved(compiler); 120 cls.ensureResolved(compiler);
115 universe.instantiatedTypes.add(type); 121 universe.instantiatedTypes.add(type);
116 if (!cls.isAbstract 122 if (!cls.isAbstract
117 // We can't use the closed-world assumption with native abstract 123 // We can't use the closed-world assumption with native abstract
118 // classes; a native abstract class may have non-abstract subclasses 124 // classes; a native abstract class may have non-abstract subclasses
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 registerClosurizedMember(member, compiler.globalDependencies); 216 registerClosurizedMember(member, compiler.globalDependencies);
211 addToWorkList(member); 217 addToWorkList(member);
212 return; 218 return;
213 } 219 }
214 // Store the member in [instanceFunctionsByName] to catch 220 // Store the member in [instanceFunctionsByName] to catch
215 // getters on the function. 221 // getters on the function.
216 Link<Element> members = instanceFunctionsByName.putIfAbsent( 222 Link<Element> members = instanceFunctionsByName.putIfAbsent(
217 memberName, () => const Link<Element>()); 223 memberName, () => const Link<Element>());
218 instanceFunctionsByName[memberName] = members.prepend(member); 224 instanceFunctionsByName[memberName] = members.prepend(member);
219 if (universe.hasInvocation(member, compiler)) { 225 if (universe.hasInvocation(member, compiler)) {
226 for (Selector selector in
227 universe.getMatchingSelectors(member, compiler)) {
228 dependencies.enqueues(getContext(), member);
229 }
220 addToWorkList(member); 230 addToWorkList(member);
221 return; 231 return;
222 } 232 }
223 } else if (member.kind == ElementKind.GETTER) { 233 } else if (member.kind == ElementKind.GETTER) {
224 if (universe.hasInvokedGetter(member, compiler)) { 234 if (universe.hasInvokedGetter(member, compiler)) {
225 addToWorkList(member); 235 addToWorkList(member);
226 return; 236 return;
227 } 237 }
228 // We don't know what selectors the returned closure accepts. If 238 // We don't know what selectors the returned closure accepts. If
229 // the set contains any selector we have to assume that it matches. 239 // the set contains any selector we have to assume that it matches.
230 if (universe.hasInvocation(member, compiler)) { 240 if (universe.hasInvocation(member, compiler)) {
231 addToWorkList(member); 241 addToWorkList(member);
232 return; 242 return;
233 } 243 }
234 } else if (member.kind == ElementKind.SETTER) { 244 } else if (member.kind == ElementKind.SETTER) {
235 if (universe.hasInvokedSetter(member, compiler)) { 245 if (universe.hasInvokedSetter(member, compiler)) {
236 addToWorkList(member); 246 addToWorkList(member);
237 return; 247 return;
238 } 248 }
239 } 249 }
240 250
241 // The element is not yet used. Add it to the list of instance 251 // The element is not yet used. Add it to the list of instance
242 // members to still be processed. 252 // members to still be processed.
243 Link<Element> members = instanceMembersByName.putIfAbsent( 253 Link<Element> members = instanceMembersByName.putIfAbsent(
244 memberName, () => const Link<Element>()); 254 memberName, () => const Link<Element>());
245 instanceMembersByName[memberName] = members.prepend(member); 255 instanceMembersByName[memberName] = members.prepend(member);
246 } 256 }
247 257
258 // TODO(karlklose): get the context.
259 getContext() => compiler.currentElement;
260
248 void enableNoSuchMethod(Element element) {} 261 void enableNoSuchMethod(Element element) {}
249 void enableIsolateSupport(LibraryElement element) {} 262 void enableIsolateSupport(LibraryElement element) {}
250 263
251 void onRegisterInstantiatedClass(ClassElement cls) { 264 void onRegisterInstantiatedClass(ClassElement cls) {
252 task.measure(() { 265 task.measure(() {
253 if (seenClasses.contains(cls)) return; 266 if (seenClasses.contains(cls)) return;
254 // The class must be resolved to compute the set of all 267 // The class must be resolved to compute the set of all
255 // supertypes. 268 // supertypes.
256 cls.ensureResolved(compiler); 269 cls.ensureResolved(compiler);
257 270
(...skipping 13 matching lines...) Expand all
271 cls, this, compiler.globalDependencies); 284 cls, this, compiler.globalDependencies);
272 } 285 }
273 processClass(cls); 286 processClass(cls);
274 for (Link<DartType> supertypes = cls.allSupertypes; 287 for (Link<DartType> supertypes = cls.allSupertypes;
275 !supertypes.isEmpty; supertypes = supertypes.tail) { 288 !supertypes.isEmpty; supertypes = supertypes.tail) {
276 processClass(supertypes.head.element); 289 processClass(supertypes.head.element);
277 } 290 }
278 }); 291 });
279 } 292 }
280 293
281 void registerNewSelector(Selector selector, 294 void registerNewSelector(Element context,
295 Selector selector,
282 Map<String, Set<Selector>> selectorsMap) { 296 Map<String, Set<Selector>> selectorsMap) {
283 String name = selector.name; 297 String name = selector.name;
284 Set<Selector> selectors = 298 Set<Selector> selectors =
285 selectorsMap.putIfAbsent(name, () => new Setlet<Selector>()); 299 selectorsMap.putIfAbsent(name, () => new Setlet<Selector>());
286 if (!selectors.contains(selector)) { 300 if (!selectors.contains(selector)) {
287 selectors.add(selector); 301 selectors.add(selector);
288 handleUnseenSelector(name, selector); 302 handleUnseenSelector(getContext(), name, selector);
289 } 303 }
290 } 304 }
291 305
292 void registerInvocation(Selector selector) { 306 void registerInvocation(Element context, Selector selector) {
293 task.measure(() { 307 task.measure(() {
294 registerNewSelector(selector, universe.invokedNames); 308 registerNewSelector(context, selector, universe.invokedNames);
295 }); 309 });
296 } 310 }
297 311
298 void registerInvokedGetter(Selector selector) { 312 void registerInvokedGetter(Element context, Selector selector) {
299 task.measure(() { 313 task.measure(() {
300 registerNewSelector(selector, universe.invokedGetters); 314 registerNewSelector(context, selector, universe.invokedGetters);
301 }); 315 });
302 } 316 }
303 317
304 void registerInvokedSetter(Selector selector) { 318 void registerInvokedSetter(Element context, Selector selector) {
305 task.measure(() { 319 task.measure(() {
306 registerNewSelector(selector, universe.invokedSetters); 320 registerNewSelector(context, selector, universe.invokedSetters);
307 }); 321 });
308 } 322 }
309 323
310 void pretendElementWasUsed(Element element, Registry registry) { 324 void pretendElementWasUsed(Element element, Registry registry) {
311 if (!compiler.backend.isNeededForReflection(element)) return; 325 if (!compiler.backend.isNeededForReflection(element)) return;
312 if (Elements.isUnresolved(element)) { 326 if (Elements.isUnresolved(element)) {
313 // Ignore. 327 // Ignore.
314 } else if (element.isSynthesized 328 } else if (element.isSynthesized
315 && element.library.isPlatformLibrary) { 329 && element.library.isPlatformLibrary) {
316 // TODO(ahe): Work-around for http://dartbug.com/11205. 330 // TODO(ahe): Work-around for http://dartbug.com/11205.
317 } else if (element.isConstructor) { 331 } else if (element.isConstructor) {
318 ClassElement cls = element.declaration.enclosingClass; 332 ClassElement cls = element.declaration.enclosingClass;
319 registerInstantiatedType(cls.rawType, registry); 333 registerInstantiatedType(cls.rawType, registry);
320 registerStaticUse(element.declaration); 334 registerStaticUse(element.declaration);
321 } else if (element.isClass) { 335 } else if (element.isClass) {
322 ClassElement cls = element.declaration; 336 ClassElement cls = element.declaration;
323 registerInstantiatedClass(cls, registry); 337 registerInstantiatedClass(cls, registry);
324 // Make sure that even abstract classes are considered instantiated. 338 // Make sure that even abstract classes are considered instantiated.
325 universe.instantiatedClasses.add(cls); 339 universe.instantiatedClasses.add(cls);
326 } else if (element.impliesType) { 340 } else if (element.impliesType) {
327 // Don't enqueue typedefs, and type variables. 341 // Don't enqueue typedefs, and type variables.
328 } else if (Elements.isStaticOrTopLevel(element)) { 342 } else if (Elements.isStaticOrTopLevel(element)) {
329 registerStaticUse(element.declaration); 343 registerStaticUse(element.declaration);
330 } else if (element.isInstanceMember) { 344 } else if (element.isInstanceMember) {
331 Selector selector = new Selector.fromElement(element, compiler); 345 Selector selector = new Selector.fromElement(element, compiler);
332 registerSelectorUse(selector); 346 registerSelectorUse(element, selector);
333 if (element.isField) { 347 if (element.isField) {
334 Selector selector = 348 Selector selector =
335 new Selector.setter(element.name, element.library); 349 new Selector.setter(element.name, element.library);
336 registerInvokedSetter(selector); 350 registerInvokedSetter(element, selector);
337 } 351 }
338 } 352 }
339 } 353 }
340 354
341 void enqueueEverything() { 355 void enqueueEverything() {
342 if (hasEnqueuedEverything) return; 356 if (hasEnqueuedEverything) return;
343 compiler.log('Enqueuing everything'); 357 compiler.log('Enqueuing everything');
344 task.ensureAllElementsByName(); 358 task.ensureAllElementsByName();
345 for (Link link in task.allElementsByName.values) { 359 for (Link link in task.allElementsByName.values) {
346 for (Element element in link) { 360 for (Element element in link) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 } 393 }
380 394
381 processInstanceMembers(String n, bool f(Element e)) { 395 processInstanceMembers(String n, bool f(Element e)) {
382 processLink(instanceMembersByName, n, f); 396 processLink(instanceMembersByName, n, f);
383 } 397 }
384 398
385 processInstanceFunctions(String n, bool f(Element e)) { 399 processInstanceFunctions(String n, bool f(Element e)) {
386 processLink(instanceFunctionsByName, n, f); 400 processLink(instanceFunctionsByName, n, f);
387 } 401 }
388 402
389 void handleUnseenSelector(String methodName, Selector selector) { 403 void handleUnseenSelector(Element context,
404 String methodName,
405 Selector selector) {
390 processInstanceMembers(methodName, (Element member) { 406 processInstanceMembers(methodName, (Element member) {
407 dependencies.enqueues(context, member);
391 if (selector.appliesUnnamed(member, compiler)) { 408 if (selector.appliesUnnamed(member, compiler)) {
392 if (member.isFunction && selector.isGetter) { 409 if (member.isFunction && selector.isGetter) {
393 registerClosurizedMember(member, compiler.globalDependencies); 410 registerClosurizedMember(member, compiler.globalDependencies);
394 } 411 }
395 if (member.isField && member.enclosingClass.isNative) { 412 if (member.isField && member.enclosingClass.isNative) {
396 if (selector.isGetter || selector.isCall) { 413 if (selector.isGetter || selector.isCall) {
397 nativeEnqueuer.registerFieldLoad(member); 414 nativeEnqueuer.registerFieldLoad(member);
398 // We have to also handle storing to the field because we only get 415 // We have to also handle storing to the field because we only get
399 // one look at each member and there might be a store we have not 416 // one look at each member and there might be a store we have not
400 // seen yet. 417 // seen yet.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 compiler.backend.registerStaticUse(element, this); 455 compiler.backend.registerStaticUse(element, this);
439 } 456 }
440 457
441 void registerGetOfStaticFunction(FunctionElement element) { 458 void registerGetOfStaticFunction(FunctionElement element) {
442 registerStaticUse(element); 459 registerStaticUse(element);
443 registerInstantiatedClass(compiler.closureClass, 460 registerInstantiatedClass(compiler.closureClass,
444 compiler.globalDependencies); 461 compiler.globalDependencies);
445 universe.staticFunctionsNeedingGetter.add(element); 462 universe.staticFunctionsNeedingGetter.add(element);
446 } 463 }
447 464
448 void registerDynamicInvocation(Selector selector) { 465 void registerDynamicInvocation(Element context, Selector selector) {
449 assert(selector != null); 466 assert(selector != null);
450 registerInvocation(selector); 467 registerInvocation(context, selector);
451 } 468 }
452 469
453 void registerSelectorUse(Selector selector) { 470 void registerSelectorUse(Element context, Selector selector) {
454 if (selector.isGetter) { 471 if (selector.isGetter) {
455 registerInvokedGetter(selector); 472 registerInvokedGetter(context, selector);
456 } else if (selector.isSetter) { 473 } else if (selector.isSetter) {
457 registerInvokedSetter(selector); 474 registerInvokedSetter(context, selector);
458 } else { 475 } else {
459 registerInvocation(selector); 476 registerInvocation(context, selector);
460 } 477 }
461 } 478 }
462 479
463 void registerDynamicGetter(Selector selector) { 480 void registerDynamicGetter(Element context, Selector selector) {
464 registerInvokedGetter(selector); 481 registerInvokedGetter(context, selector);
465 } 482 }
466 483
467 void registerDynamicSetter(Selector selector) { 484 void registerDynamicSetter(Element context, Selector selector) {
468 registerInvokedSetter(selector); 485 registerInvokedSetter(context, selector);
469 } 486 }
470 487
471 void registerGetterForSuperMethod(Element element) { 488 void registerGetterForSuperMethod(Element element) {
472 universe.methodsNeedingSuperGetter.add(element); 489 universe.methodsNeedingSuperGetter.add(element);
473 } 490 }
474 491
475 void registerFieldGetter(Element element) { 492 void registerFieldGetter(Element element) {
476 universe.fieldGetters.add(element); 493 universe.fieldGetters.add(element);
477 } 494 }
478 495
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 final Map<Element, TreeElements> resolvedElements; 581 final Map<Element, TreeElements> resolvedElements;
565 582
566 final Queue<ResolutionWorkItem> queue; 583 final Queue<ResolutionWorkItem> queue;
567 584
568 /** 585 /**
569 * A deferred task queue for the resolution phase which is processed 586 * A deferred task queue for the resolution phase which is processed
570 * when the resolution queue has been emptied. 587 * when the resolution queue has been emptied.
571 */ 588 */
572 final Queue<DeferredTask> deferredTaskQueue; 589 final Queue<DeferredTask> deferredTaskQueue;
573 590
591 Relations dependencies;
592
574 ResolutionEnqueuer(Compiler compiler, 593 ResolutionEnqueuer(Compiler compiler,
575 ItemCompilationContext itemCompilationContextCreator()) 594 ItemCompilationContext itemCompilationContextCreator())
576 : super('resolution enqueuer', compiler, itemCompilationContextCreator), 595 : super('resolution enqueuer', compiler, itemCompilationContextCreator),
577 resolvedElements = new Map<Element, TreeElements>(), 596 resolvedElements = new Map<Element, TreeElements>(),
578 queue = new Queue<ResolutionWorkItem>(), 597 queue = new Queue<ResolutionWorkItem>(),
579 deferredTaskQueue = new Queue<DeferredTask>(); 598 deferredTaskQueue = new Queue<DeferredTask>() {
599 dependencies = new Relations(this);
600 }
580 601
581 bool get isResolutionQueue => true; 602 bool get isResolutionQueue => true;
582 603
583 bool isProcessed(Element member) => resolvedElements.containsKey(member); 604 bool isProcessed(Element member) => resolvedElements.containsKey(member);
584 605
585 /// Returns [:true:] if [element] has actually been used. 606 /// Returns [:true:] if [element] has actually been used.
586 bool isLive(Element element) { 607 bool isLive(Element element) {
587 if (seenClasses.contains(element)) return true; 608 if (seenClasses.contains(element)) return true;
588 if (getCachedElements(element) != null) return true; 609 if (getCachedElements(element) != null) return true;
589 return false; 610 return false;
590 } 611 }
591 612
592 TreeElements getCachedElements(Element element) { 613 TreeElements getCachedElements(Element element) {
593 // TODO(ngeoffray): Get rid of this check. 614 // TODO(ngeoffray): Get rid of this check.
594 if (element.enclosingElement.isClosure) { 615 if (element.enclosingElement.isClosure) {
595 closureMapping.ClosureClassElement cls = element.enclosingElement; 616 closureMapping.ClosureClassElement cls = element.enclosingElement;
596 element = cls.methodElement; 617 element = cls.methodElement;
597 } else if (element.isGenerativeConstructorBody) { 618 } else if (element.isGenerativeConstructorBody) {
598 ConstructorBodyElement body = element; 619 ConstructorBodyElement body = element;
599 element = body.constructor; 620 element = body.constructor;
600 } 621 }
601 Element owner = element.outermostEnclosingMemberOrTopLevel; 622 Element owner = element.outermostEnclosingMemberOrTopLevel;
602 if (owner == null) { 623 if (owner == null) {
603 owner = element; 624 owner = element;
604 } 625 }
605 return resolvedElements[owner.declaration]; 626 return resolvedElements[owner.declaration];
606 } 627 }
607 628
608 void internalAddToWorkList(Element element) { 629 bool internalAddToWorkList(Element element) {
609 assert(invariant(element, element is AnalyzableElement, 630 assert(invariant(element, element is AnalyzableElement,
610 message: 'Element $element is not analyzable.')); 631 message: 'Element $element is not analyzable.'));
611 if (getCachedElements(element) != null) return; 632 if (getCachedElements(element) != null) return false;
612 if (queueIsClosed) { 633 if (queueIsClosed) {
613 throw new SpannableAssertionFailure(element, 634 throw new SpannableAssertionFailure(element,
614 "Resolution work list is closed. Trying to add $element."); 635 "Resolution work list is closed. Trying to add $element.");
615 } 636 }
616 637
617 compiler.world.registerUsedElement(element); 638 compiler.world.registerUsedElement(element);
618 639
619 queue.add(new ResolutionWorkItem(element, itemCompilationContextCreator())); 640 queue.add(new ResolutionWorkItem(element, itemCompilationContextCreator()));
620 641
621 // Enable isolate support if we start using something from the isolate 642 // Enable isolate support if we start using something from the isolate
(...skipping 23 matching lines...) Expand all
645 compiler.enabledRuntimeType = true; 666 compiler.enabledRuntimeType = true;
646 // TODO(ahe): Record precise dependency here. 667 // TODO(ahe): Record precise dependency here.
647 compiler.backend.registerRuntimeType(this, compiler.globalDependencies); 668 compiler.backend.registerRuntimeType(this, compiler.globalDependencies);
648 } else if (element == compiler.functionApplyMethod) { 669 } else if (element == compiler.functionApplyMethod) {
649 compiler.enabledFunctionApply = true; 670 compiler.enabledFunctionApply = true;
650 } else if (element == compiler.invokeOnMethod) { 671 } else if (element == compiler.invokeOnMethod) {
651 compiler.enabledInvokeOn = true; 672 compiler.enabledInvokeOn = true;
652 } 673 }
653 674
654 nativeEnqueuer.registerElement(element); 675 nativeEnqueuer.registerElement(element);
676 return true;
655 } 677 }
656 678
657 void enableIsolateSupport(LibraryElement element) { 679 void enableIsolateSupport(LibraryElement element) {
658 compiler.isolateLibrary = element.patch; 680 compiler.isolateLibrary = element.patch;
659 for (String name in const [Compiler.START_ROOT_ISOLATE, 681 for (String name in const [Compiler.START_ROOT_ISOLATE,
660 '_currentIsolate', 682 '_currentIsolate',
661 '_callInIsolate']) { 683 '_callInIsolate']) {
662 Element element = compiler.isolateHelperLibrary.find(name); 684 Element element = compiler.isolateHelperLibrary.find(name);
663 addToWorkList(element); 685 addToWorkList(element);
664 compiler.globalDependencies.registerDependency(element); 686 compiler.globalDependencies.registerDependency(element);
665 } 687 }
666 } 688 }
667 689
668 void enableNoSuchMethod(Element element) { 690 void enableNoSuchMethod(Element element) {
669 if (compiler.enabledNoSuchMethod) return; 691 if (compiler.enabledNoSuchMethod) return;
670 if (compiler.backend.isDefaultNoSuchMethodImplementation(element)) return; 692 if (compiler.backend.isDefaultNoSuchMethodImplementation(element)) return;
671 693
672 Selector selector = compiler.noSuchMethodSelector; 694 Selector selector = compiler.noSuchMethodSelector;
673 compiler.enabledNoSuchMethod = true; 695 compiler.enabledNoSuchMethod = true;
674 compiler.backend.enableNoSuchMethod(this); 696 compiler.backend.enableNoSuchMethod(element, this);
675 } 697 }
676 698
677 /** 699 /**
678 * Adds an action to the deferred task queue. 700 * Adds an action to the deferred task queue.
679 * 701 *
680 * The action is performed the next time the resolution queue has been 702 * The action is performed the next time the resolution queue has been
681 * emptied. 703 * emptied.
682 * 704 *
683 * The queue is processed in FIFO order. 705 * The queue is processed in FIFO order.
684 */ 706 */
(...skipping 26 matching lines...) Expand all
711 log('Resolved ${resolvedElements.length} elements.'); 733 log('Resolved ${resolvedElements.length} elements.');
712 } 734 }
713 } 735 }
714 736
715 /// [Enqueuer] which is specific to code generation. 737 /// [Enqueuer] which is specific to code generation.
716 class CodegenEnqueuer extends Enqueuer { 738 class CodegenEnqueuer extends Enqueuer {
717 final Queue<CodegenWorkItem> queue; 739 final Queue<CodegenWorkItem> queue;
718 final Map<Element, js.Expression> generatedCode = 740 final Map<Element, js.Expression> generatedCode =
719 new Map<Element, js.Expression>(); 741 new Map<Element, js.Expression>();
720 742
743 Relations dependencies;
744
721 CodegenEnqueuer(Compiler compiler, 745 CodegenEnqueuer(Compiler compiler,
722 ItemCompilationContext itemCompilationContextCreator()) 746 ItemCompilationContext itemCompilationContextCreator())
723 : super('codegen enqueuer', compiler, itemCompilationContextCreator), 747 : super('codegen enqueuer', compiler, itemCompilationContextCreator),
724 queue = new Queue<CodegenWorkItem>(); 748 queue = new Queue<CodegenWorkItem>() {
749 dependencies = new Relations(this);
750 }
725 751
726 bool isProcessed(Element member) => 752 bool isProcessed(Element member) =>
727 member.isAbstract || generatedCode.containsKey(member); 753 member.isAbstract || generatedCode.containsKey(member);
728 754
729 void internalAddToWorkList(Element element) { 755 bool internalAddToWorkList(Element element) {
730 // Don't generate code for foreign elements. 756 // Don't generate code for foreign elements.
731 if (element.isForeign(compiler)) return; 757 if (element.isForeign(compiler)) return false;
732 758
733 // Codegen inlines field initializers. It only needs to generate 759 // Codegen inlines field initializers. It only needs to generate
734 // code for checked setters. 760 // code for checked setters.
735 if (element.isField && element.isInstanceMember) { 761 if (element.isField && element.isInstanceMember) {
736 if (!compiler.enableTypeAssertions 762 if (!compiler.enableTypeAssertions
737 || element.enclosingElement.isClosure) { 763 || element.enclosingElement.isClosure) {
738 return; 764 return false;
739 } 765 }
740 } 766 }
741 767
742 if (queueIsClosed) { 768 if (queueIsClosed) {
743 throw new SpannableAssertionFailure(element, 769 throw new SpannableAssertionFailure(element,
744 "Codegen work list is closed. Trying to add $element"); 770 "Codegen work list is closed. Trying to add $element");
745 } 771 }
746 CodegenWorkItem workItem = new CodegenWorkItem( 772 CodegenWorkItem workItem = new CodegenWorkItem(
747 element, itemCompilationContextCreator()); 773 element, itemCompilationContextCreator());
748 queue.add(workItem); 774 queue.add(workItem);
775 return true;
749 } 776 }
750 777
751 void _logSpecificSummary(log(message)) { 778 void _logSpecificSummary(log(message)) {
752 log('Compiled ${generatedCode.length} methods.'); 779 log('Compiled ${generatedCode.length} methods.');
753 } 780 }
754 } 781 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698