| OLD | NEW |
| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 static final TRACE_MIRROR_ENQUEUING = | 42 static final TRACE_MIRROR_ENQUEUING = |
| 43 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); | 43 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); |
| 44 | 44 |
| 45 bool queueIsClosed = false; | 45 bool queueIsClosed = false; |
| 46 EnqueueTask task; | 46 EnqueueTask task; |
| 47 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask | 47 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
| 48 | 48 |
| 49 bool hasEnqueuedReflectiveElements = false; | 49 bool hasEnqueuedReflectiveElements = false; |
| 50 bool hasEnqueuedReflectiveStaticFields = false; | 50 bool hasEnqueuedReflectiveStaticFields = false; |
| 51 | 51 |
| 52 CompilationInformation get compilationInfo; |
| 53 |
| 52 Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator); | 54 Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator); |
| 53 | 55 |
| 54 Queue<WorkItem> get queue; | 56 Queue<WorkItem> get queue; |
| 55 bool get queueIsEmpty => queue.isEmpty; | 57 bool get queueIsEmpty => queue.isEmpty; |
| 56 | 58 |
| 57 /// Returns [:true:] if this enqueuer is the resolution enqueuer. | 59 /// Returns [:true:] if this enqueuer is the resolution enqueuer. |
| 58 bool get isResolutionQueue => false; | 60 bool get isResolutionQueue => false; |
| 59 | 61 |
| 60 QueueFilter get filter => compiler.enqueuerFilter; | 62 QueueFilter get filter => compiler.enqueuerFilter; |
| 61 | 63 |
| 62 /// Returns [:true:] if [member] has been processed by this enqueuer. | 64 /// Returns [:true:] if [member] has been processed by this enqueuer. |
| 63 bool isProcessed(Element member); | 65 bool isProcessed(Element member); |
| 64 | 66 |
| 65 /** | 67 /** |
| 66 * Documentation wanted -- johnniwinther | 68 * Documentation wanted -- johnniwinther |
| 67 * | 69 * |
| 68 * Invariant: [element] must be a declaration element. | 70 * Invariant: [element] must be a declaration element. |
| 69 */ | 71 */ |
| 70 void addToWorkList(Element element) { | 72 void addToWorkList(Element element) { |
| 71 assert(invariant(element, element.isDeclaration)); | 73 assert(invariant(element, element.isDeclaration)); |
| 72 internalAddToWorkList(element); | 74 if (internalAddToWorkList(element)) { |
| 75 compilationInfo.addsToWorkList(compiler.currentElement, element); |
| 76 } |
| 73 } | 77 } |
| 74 | 78 |
| 75 /** | 79 /** |
| 76 * Adds [element] to the work list if it has not already been processed. | 80 * Adds [element] to the work list if it has not already been processed. |
| 81 * |
| 82 * Returns [true] if the element was actually added to the queue. |
| 77 */ | 83 */ |
| 78 void internalAddToWorkList(Element element); | 84 bool internalAddToWorkList(Element element); |
| 79 | 85 |
| 80 void registerInstantiatedType(InterfaceType type, Registry registry, | 86 void registerInstantiatedType(InterfaceType type, Registry registry, |
| 81 {mirrorUsage: false}) { | 87 {mirrorUsage: false}) { |
| 82 task.measure(() { | 88 task.measure(() { |
| 83 ClassElement cls = type.element; | 89 ClassElement cls = type.element; |
| 84 registry.registerDependency(cls); | 90 registry.registerDependency(cls); |
| 85 cls.ensureResolved(compiler); | 91 cls.ensureResolved(compiler); |
| 86 universe.instantiatedTypes.add(type); | 92 universe.instantiatedTypes.add(type); |
| 87 if (!cls.isAbstract | 93 if (!cls.isAbstract |
| 88 // We can't use the closed-world assumption with native abstract | 94 // We can't use the closed-world assumption with native abstract |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 registerClosurizedMember(member, compiler.globalDependencies); | 182 registerClosurizedMember(member, compiler.globalDependencies); |
| 177 addToWorkList(member); | 183 addToWorkList(member); |
| 178 return; | 184 return; |
| 179 } | 185 } |
| 180 // Store the member in [instanceFunctionsByName] to catch | 186 // Store the member in [instanceFunctionsByName] to catch |
| 181 // getters on the function. | 187 // getters on the function. |
| 182 Link<Element> members = instanceFunctionsByName.putIfAbsent( | 188 Link<Element> members = instanceFunctionsByName.putIfAbsent( |
| 183 memberName, () => const Link<Element>()); | 189 memberName, () => const Link<Element>()); |
| 184 instanceFunctionsByName[memberName] = members.prepend(member); | 190 instanceFunctionsByName[memberName] = members.prepend(member); |
| 185 if (universe.hasInvocation(member, compiler)) { | 191 if (universe.hasInvocation(member, compiler)) { |
| 192 compilationInfo.enqueues(getContext(), member); |
| 186 addToWorkList(member); | 193 addToWorkList(member); |
| 187 return; | 194 return; |
| 188 } | 195 } |
| 189 } else if (member.kind == ElementKind.GETTER) { | 196 } else if (member.kind == ElementKind.GETTER) { |
| 190 if (universe.hasInvokedGetter(member, compiler)) { | 197 if (universe.hasInvokedGetter(member, compiler)) { |
| 191 addToWorkList(member); | 198 addToWorkList(member); |
| 192 return; | 199 return; |
| 193 } | 200 } |
| 194 // We don't know what selectors the returned closure accepts. If | 201 // We don't know what selectors the returned closure accepts. If |
| 195 // the set contains any selector we have to assume that it matches. | 202 // the set contains any selector we have to assume that it matches. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 207 // The element is not yet used. Add it to the list of instance | 214 // The element is not yet used. Add it to the list of instance |
| 208 // members to still be processed. | 215 // members to still be processed. |
| 209 Link<Element> members = instanceMembersByName.putIfAbsent( | 216 Link<Element> members = instanceMembersByName.putIfAbsent( |
| 210 memberName, () => const Link<Element>()); | 217 memberName, () => const Link<Element>()); |
| 211 instanceMembersByName[memberName] = members.prepend(member); | 218 instanceMembersByName[memberName] = members.prepend(member); |
| 212 } | 219 } |
| 213 | 220 |
| 214 void enableNoSuchMethod(Element element) {} | 221 void enableNoSuchMethod(Element element) {} |
| 215 void enableIsolateSupport() {} | 222 void enableIsolateSupport() {} |
| 216 | 223 |
| 224 Element getContext() => compiler.currentElement; |
| 225 |
| 217 void onRegisterInstantiatedClass(ClassElement cls) { | 226 void onRegisterInstantiatedClass(ClassElement cls) { |
| 218 task.measure(() { | 227 task.measure(() { |
| 219 if (seenClasses.contains(cls)) return; | 228 if (seenClasses.contains(cls)) return; |
| 220 // The class must be resolved to compute the set of all | 229 // The class must be resolved to compute the set of all |
| 221 // supertypes. | 230 // supertypes. |
| 222 cls.ensureResolved(compiler); | 231 cls.ensureResolved(compiler); |
| 223 | 232 |
| 224 void processClass(ClassElement cls) { | 233 void processClass(ClassElement cls) { |
| 225 if (seenClasses.contains(cls)) return; | 234 if (seenClasses.contains(cls)) return; |
| 226 | 235 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 238 cls, this, compiler.globalDependencies); | 247 cls, this, compiler.globalDependencies); |
| 239 } | 248 } |
| 240 processClass(cls); | 249 processClass(cls); |
| 241 for (Link<DartType> supertypes = cls.allSupertypes; | 250 for (Link<DartType> supertypes = cls.allSupertypes; |
| 242 !supertypes.isEmpty; supertypes = supertypes.tail) { | 251 !supertypes.isEmpty; supertypes = supertypes.tail) { |
| 243 processClass(supertypes.head.element); | 252 processClass(supertypes.head.element); |
| 244 } | 253 } |
| 245 }); | 254 }); |
| 246 } | 255 } |
| 247 | 256 |
| 248 void registerNewSelector(Selector selector, | 257 void registerNewSelector(Element context, |
| 258 Selector selector, |
| 249 Map<String, Set<Selector>> selectorsMap) { | 259 Map<String, Set<Selector>> selectorsMap) { |
| 250 String name = selector.name; | 260 String name = selector.name; |
| 251 Set<Selector> selectors = | 261 Set<Selector> selectors = |
| 252 selectorsMap.putIfAbsent(name, () => new Setlet<Selector>()); | 262 selectorsMap.putIfAbsent(name, () => new Setlet<Selector>()); |
| 253 if (!selectors.contains(selector)) { | 263 if (!selectors.contains(selector)) { |
| 254 selectors.add(selector); | 264 selectors.add(selector); |
| 255 handleUnseenSelector(name, selector); | 265 handleUnseenSelector(context, name, selector); |
| 256 } | 266 } |
| 257 } | 267 } |
| 258 | 268 |
| 259 void registerInvocation(Selector selector) { | 269 void registerInvocation(Element context, Selector selector) { |
| 260 task.measure(() { | 270 task.measure(() { |
| 261 registerNewSelector(selector, universe.invokedNames); | 271 registerNewSelector(context, selector, universe.invokedNames); |
| 262 }); | 272 }); |
| 263 } | 273 } |
| 264 | 274 |
| 265 void registerInvokedGetter(Selector selector) { | 275 void registerInvokedGetter(Element context, Selector selector) { |
| 266 task.measure(() { | 276 task.measure(() { |
| 267 registerNewSelector(selector, universe.invokedGetters); | 277 registerNewSelector(context, selector, universe.invokedGetters); |
| 268 }); | 278 }); |
| 269 } | 279 } |
| 270 | 280 |
| 271 void registerInvokedSetter(Selector selector) { | 281 void registerInvokedSetter(Element context, Selector selector) { |
| 272 task.measure(() { | 282 task.measure(() { |
| 273 registerNewSelector(selector, universe.invokedSetters); | 283 registerNewSelector(context, selector, universe.invokedSetters); |
| 274 }); | 284 }); |
| 275 } | 285 } |
| 276 | 286 |
| 277 /** | 287 /** |
| 278 * Decides whether an element should be included to satisfy requirements | 288 * Decides whether an element should be included to satisfy requirements |
| 279 * of the mirror system. [includedEnclosing] provides a hint whether the | 289 * of the mirror system. [includedEnclosing] provides a hint whether the |
| 280 * enclosing element was included. | 290 * enclosing element was included. |
| 281 * | 291 * |
| 282 * The actual implementation depends on the current compiler phase. | 292 * The actual implementation depends on the current compiler phase. |
| 283 */ | 293 */ |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 // Do not enqueue typedefs. | 326 // Do not enqueue typedefs. |
| 317 && !element.impliesType) { | 327 && !element.impliesType) { |
| 318 logEnqueueReflectiveAction(element); | 328 logEnqueueReflectiveAction(element); |
| 319 if (Elements.isStaticOrTopLevel(element)) { | 329 if (Elements.isStaticOrTopLevel(element)) { |
| 320 registerStaticUse(element.declaration); | 330 registerStaticUse(element.declaration); |
| 321 } else if (element.isInstanceMember) { | 331 } else if (element.isInstanceMember) { |
| 322 // We need to enqueue all members matching this one in subclasses, as | 332 // We need to enqueue all members matching this one in subclasses, as |
| 323 // well. | 333 // well. |
| 324 // TODO(herhut): Use TypedSelector.subtype for enqueueing | 334 // TODO(herhut): Use TypedSelector.subtype for enqueueing |
| 325 Selector selector = new Selector.fromElement(element, compiler); | 335 Selector selector = new Selector.fromElement(element, compiler); |
| 326 registerSelectorUse(selector); | 336 registerSelectorUse(element, selector); |
| 327 if (element.isField) { | 337 if (element.isField) { |
| 328 Selector selector = | 338 Selector selector = |
| 329 new Selector.setter(element.name, element.library); | 339 new Selector.setter(element.name, element.library); |
| 330 registerInvokedSetter(selector); | 340 registerInvokedSetter(element, selector); |
| 331 } | 341 } |
| 332 } | 342 } |
| 333 } | 343 } |
| 334 } | 344 } |
| 335 | 345 |
| 336 /// Enqeue the member [element] if it is required for reflection. | 346 /// Enqeue the member [element] if it is required for reflection. |
| 337 /// | 347 /// |
| 338 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 348 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
| 339 /// needed for reflection. | 349 /// needed for reflection. |
| 340 void enqueueReflectiveElementsInClass(ClassElement cls, | 350 void enqueueReflectiveElementsInClass(ClassElement cls, |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 } | 467 } |
| 458 | 468 |
| 459 processInstanceMembers(String n, bool f(Element e)) { | 469 processInstanceMembers(String n, bool f(Element e)) { |
| 460 processLink(instanceMembersByName, n, f); | 470 processLink(instanceMembersByName, n, f); |
| 461 } | 471 } |
| 462 | 472 |
| 463 processInstanceFunctions(String n, bool f(Element e)) { | 473 processInstanceFunctions(String n, bool f(Element e)) { |
| 464 processLink(instanceFunctionsByName, n, f); | 474 processLink(instanceFunctionsByName, n, f); |
| 465 } | 475 } |
| 466 | 476 |
| 467 void handleUnseenSelector(String methodName, Selector selector) { | 477 void handleUnseenSelector(Element context, |
| 478 String methodName, |
| 479 Selector selector) { |
| 468 processInstanceMembers(methodName, (Element member) { | 480 processInstanceMembers(methodName, (Element member) { |
| 481 compilationInfo.enqueues(context, member); |
| 469 if (selector.appliesUnnamed(member, compiler)) { | 482 if (selector.appliesUnnamed(member, compiler)) { |
| 470 if (member.isFunction && selector.isGetter) { | 483 if (member.isFunction && selector.isGetter) { |
| 471 registerClosurizedMember(member, compiler.globalDependencies); | 484 registerClosurizedMember(member, compiler.globalDependencies); |
| 472 } | 485 } |
| 473 if (member.isField && member.enclosingClass.isNative) { | 486 if (member.isField && member.enclosingClass.isNative) { |
| 474 if (selector.isGetter || selector.isCall) { | 487 if (selector.isGetter || selector.isCall) { |
| 475 nativeEnqueuer.registerFieldLoad(member); | 488 nativeEnqueuer.registerFieldLoad(member); |
| 476 // We have to also handle storing to the field because we only get | 489 // We have to also handle storing to the field because we only get |
| 477 // one look at each member and there might be a store we have not | 490 // one look at each member and there might be a store we have not |
| 478 // seen yet. | 491 // seen yet. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 addToWorkList(element); | 528 addToWorkList(element); |
| 516 compiler.backend.registerStaticUse(element, this); | 529 compiler.backend.registerStaticUse(element, this); |
| 517 } | 530 } |
| 518 | 531 |
| 519 void registerGetOfStaticFunction(FunctionElement element) { | 532 void registerGetOfStaticFunction(FunctionElement element) { |
| 520 registerStaticUse(element); | 533 registerStaticUse(element); |
| 521 compiler.backend.registerGetOfStaticFunction(this); | 534 compiler.backend.registerGetOfStaticFunction(this); |
| 522 universe.staticFunctionsNeedingGetter.add(element); | 535 universe.staticFunctionsNeedingGetter.add(element); |
| 523 } | 536 } |
| 524 | 537 |
| 525 void registerDynamicInvocation(Selector selector) { | 538 void registerDynamicInvocation(Element context, Selector selector) { |
| 526 assert(selector != null); | 539 assert(selector != null); |
| 527 registerInvocation(selector); | 540 registerInvocation(context, selector); |
| 528 } | 541 } |
| 529 | 542 |
| 530 void registerSelectorUse(Selector selector) { | 543 void registerSelectorUse(Element context, Selector selector) { |
| 531 if (selector.isGetter) { | 544 if (selector.isGetter) { |
| 532 registerInvokedGetter(selector); | 545 registerInvokedGetter(context, selector); |
| 533 } else if (selector.isSetter) { | 546 } else if (selector.isSetter) { |
| 534 registerInvokedSetter(selector); | 547 registerInvokedSetter(context, selector); |
| 535 } else { | 548 } else { |
| 536 registerInvocation(selector); | 549 registerInvocation(context, selector); |
| 537 } | 550 } |
| 538 } | 551 } |
| 539 | 552 |
| 540 void registerDynamicGetter(Selector selector) { | 553 void registerDynamicGetter(Element context, Selector selector) { |
| 541 registerInvokedGetter(selector); | 554 registerInvokedGetter(context, selector); |
| 542 } | 555 } |
| 543 | 556 |
| 544 void registerDynamicSetter(Selector selector) { | 557 void registerDynamicSetter(Element context, Selector selector) { |
| 545 registerInvokedSetter(selector); | 558 registerInvokedSetter(context, selector); |
| 546 } | 559 } |
| 547 | 560 |
| 548 void registerGetterForSuperMethod(Element element) { | 561 void registerGetterForSuperMethod(Element element) { |
| 549 universe.methodsNeedingSuperGetter.add(element); | 562 universe.methodsNeedingSuperGetter.add(element); |
| 550 } | 563 } |
| 551 | 564 |
| 552 void registerFieldGetter(Element element) { | 565 void registerFieldGetter(Element element) { |
| 553 universe.fieldGetters.add(element); | 566 universe.fieldGetters.add(element); |
| 554 } | 567 } |
| 555 | 568 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 final Set<AstElement> resolvedElements; | 656 final Set<AstElement> resolvedElements; |
| 644 | 657 |
| 645 final Queue<ResolutionWorkItem> queue; | 658 final Queue<ResolutionWorkItem> queue; |
| 646 | 659 |
| 647 /** | 660 /** |
| 648 * A deferred task queue for the resolution phase which is processed | 661 * A deferred task queue for the resolution phase which is processed |
| 649 * when the resolution queue has been emptied. | 662 * when the resolution queue has been emptied. |
| 650 */ | 663 */ |
| 651 final Queue<DeferredTask> deferredTaskQueue; | 664 final Queue<DeferredTask> deferredTaskQueue; |
| 652 | 665 |
| 666 CompilationInformation compilationInfo; |
| 667 |
| 653 ResolutionEnqueuer(Compiler compiler, | 668 ResolutionEnqueuer(Compiler compiler, |
| 654 ItemCompilationContext itemCompilationContextCreator()) | 669 ItemCompilationContext itemCompilationContextCreator()) |
| 655 : super('resolution enqueuer', compiler, itemCompilationContextCreator), | 670 : super('resolution enqueuer', compiler, itemCompilationContextCreator), |
| 656 resolvedElements = new Set<AstElement>(), | 671 resolvedElements = new Set<AstElement>(), |
| 657 queue = new Queue<ResolutionWorkItem>(), | 672 queue = new Queue<ResolutionWorkItem>(), |
| 658 deferredTaskQueue = new Queue<DeferredTask>(); | 673 deferredTaskQueue = new Queue<DeferredTask>() { |
| 674 compilationInfo = new CompilationInformation(this); |
| 675 } |
| 659 | 676 |
| 660 bool get isResolutionQueue => true; | 677 bool get isResolutionQueue => true; |
| 661 | 678 |
| 662 bool isProcessed(Element member) => resolvedElements.contains(member); | 679 bool isProcessed(Element member) => resolvedElements.contains(member); |
| 663 | 680 |
| 664 /// Returns `true` if [element] has been processed by the resolution enqueuer. | 681 /// Returns `true` if [element] has been processed by the resolution enqueuer. |
| 665 bool hasBeenResolved(Element element) { | 682 bool hasBeenResolved(Element element) { |
| 666 return resolvedElements.contains(element.analyzableElement.declaration); | 683 return resolvedElements.contains(element.analyzableElement.declaration); |
| 667 } | 684 } |
| 668 | 685 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 684 * | 701 * |
| 685 * During resolution, we have to resort to matching elements against the | 702 * During resolution, we have to resort to matching elements against the |
| 686 * [MirrorsUsed] pattern, as we do not have a complete picture of the world, | 703 * [MirrorsUsed] pattern, as we do not have a complete picture of the world, |
| 687 * yet. | 704 * yet. |
| 688 */ | 705 */ |
| 689 bool shouldIncludeElementDueToMirrors(Element element, | 706 bool shouldIncludeElementDueToMirrors(Element element, |
| 690 {bool includedEnclosing}) { | 707 {bool includedEnclosing}) { |
| 691 return includedEnclosing || compiler.backend.requiredByMirrorSystem(element)
; | 708 return includedEnclosing || compiler.backend.requiredByMirrorSystem(element)
; |
| 692 } | 709 } |
| 693 | 710 |
| 694 void internalAddToWorkList(Element element) { | 711 bool internalAddToWorkList(Element element) { |
| 695 assert(invariant(element, element is AnalyzableElement, | 712 assert(invariant(element, element is AnalyzableElement, |
| 696 message: 'Element $element is not analyzable.')); | 713 message: 'Element $element is not analyzable.')); |
| 697 if (hasBeenResolved(element)) return; | 714 if (hasBeenResolved(element)) return false; |
| 698 if (queueIsClosed) { | 715 if (queueIsClosed) { |
| 699 throw new SpannableAssertionFailure(element, | 716 throw new SpannableAssertionFailure(element, |
| 700 "Resolution work list is closed. Trying to add $element."); | 717 "Resolution work list is closed. Trying to add $element."); |
| 701 } | 718 } |
| 702 | 719 |
| 703 compiler.world.registerUsedElement(element); | 720 compiler.world.registerUsedElement(element); |
| 704 | 721 |
| 705 queue.add(new ResolutionWorkItem(element, itemCompilationContextCreator())); | 722 queue.add(new ResolutionWorkItem(element, itemCompilationContextCreator())); |
| 706 | 723 |
| 707 // Enable isolate support if we start using something from the isolate | 724 // Enable isolate support if we start using something from the isolate |
| (...skipping 21 matching lines...) Expand all Loading... |
| 729 // that constructors know whether they need to generate code for | 746 // that constructors know whether they need to generate code for |
| 730 // runtime type. | 747 // runtime type. |
| 731 compiler.enabledRuntimeType = true; | 748 compiler.enabledRuntimeType = true; |
| 732 // TODO(ahe): Record precise dependency here. | 749 // TODO(ahe): Record precise dependency here. |
| 733 compiler.backend.registerRuntimeType(this, compiler.globalDependencies); | 750 compiler.backend.registerRuntimeType(this, compiler.globalDependencies); |
| 734 } else if (element == compiler.functionApplyMethod) { | 751 } else if (element == compiler.functionApplyMethod) { |
| 735 compiler.enabledFunctionApply = true; | 752 compiler.enabledFunctionApply = true; |
| 736 } | 753 } |
| 737 | 754 |
| 738 nativeEnqueuer.registerElement(element); | 755 nativeEnqueuer.registerElement(element); |
| 756 return true; |
| 739 } | 757 } |
| 740 | 758 |
| 741 void enableIsolateSupport() { | 759 void enableIsolateSupport() { |
| 742 compiler.hasIsolateSupport = true; | 760 compiler.hasIsolateSupport = true; |
| 743 compiler.backend.enableIsolateSupport(this); | 761 compiler.backend.enableIsolateSupport(this); |
| 744 } | 762 } |
| 745 | 763 |
| 746 void enableNoSuchMethod(Element element) { | 764 void enableNoSuchMethod(Element element) { |
| 747 if (compiler.enabledNoSuchMethod) return; | 765 if (compiler.enabledNoSuchMethod) return; |
| 748 if (compiler.backend.isDefaultNoSuchMethodImplementation(element)) return; | 766 if (compiler.backend.isDefaultNoSuchMethodImplementation(element)) return; |
| 749 | 767 |
| 750 Selector selector = compiler.noSuchMethodSelector; | 768 Selector selector = compiler.noSuchMethodSelector; |
| 751 compiler.enabledNoSuchMethod = true; | 769 compiler.enabledNoSuchMethod = true; |
| 752 compiler.backend.enableNoSuchMethod(this); | 770 compiler.backend.enableNoSuchMethod(element, this); |
| 753 } | 771 } |
| 754 | 772 |
| 755 /** | 773 /** |
| 756 * Adds an action to the deferred task queue. | 774 * Adds an action to the deferred task queue. |
| 757 * | 775 * |
| 758 * The action is performed the next time the resolution queue has been | 776 * The action is performed the next time the resolution queue has been |
| 759 * emptied. | 777 * emptied. |
| 760 * | 778 * |
| 761 * The queue is processed in FIFO order. | 779 * The queue is processed in FIFO order. |
| 762 */ | 780 */ |
| (...skipping 28 matching lines...) Expand all Loading... |
| 791 } | 809 } |
| 792 | 810 |
| 793 /// [Enqueuer] which is specific to code generation. | 811 /// [Enqueuer] which is specific to code generation. |
| 794 class CodegenEnqueuer extends Enqueuer { | 812 class CodegenEnqueuer extends Enqueuer { |
| 795 final Queue<CodegenWorkItem> queue; | 813 final Queue<CodegenWorkItem> queue; |
| 796 final Map<Element, js.Expression> generatedCode = | 814 final Map<Element, js.Expression> generatedCode = |
| 797 new Map<Element, js.Expression>(); | 815 new Map<Element, js.Expression>(); |
| 798 | 816 |
| 799 final Set<Element> newlyEnqueuedElements; | 817 final Set<Element> newlyEnqueuedElements; |
| 800 | 818 |
| 819 CompilationInformation compilationInfo; |
| 820 |
| 801 CodegenEnqueuer(Compiler compiler, | 821 CodegenEnqueuer(Compiler compiler, |
| 802 ItemCompilationContext itemCompilationContextCreator()) | 822 ItemCompilationContext itemCompilationContextCreator()) |
| 803 : queue = new Queue<CodegenWorkItem>(), | 823 : queue = new Queue<CodegenWorkItem>(), |
| 804 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), | 824 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), |
| 805 super('codegen enqueuer', compiler, itemCompilationContextCreator); | 825 super('codegen enqueuer', compiler, itemCompilationContextCreator) { |
| 826 compilationInfo = new CompilationInformation(this); |
| 827 } |
| 806 | 828 |
| 807 bool isProcessed(Element member) => | 829 bool isProcessed(Element member) => |
| 808 member.isAbstract || generatedCode.containsKey(member); | 830 member.isAbstract || generatedCode.containsKey(member); |
| 809 | 831 |
| 810 /** | 832 /** |
| 811 * Decides whether an element should be included to satisfy requirements | 833 * Decides whether an element should be included to satisfy requirements |
| 812 * of the mirror system. | 834 * of the mirror system. |
| 813 * | 835 * |
| 814 * For code generation, we rely on the precomputed set of elements that takes | 836 * For code generation, we rely on the precomputed set of elements that takes |
| 815 * subtyping constraints into account. | 837 * subtyping constraints into account. |
| 816 */ | 838 */ |
| 817 bool shouldIncludeElementDueToMirrors(Element element, | 839 bool shouldIncludeElementDueToMirrors(Element element, |
| 818 {bool includedEnclosing}) { | 840 {bool includedEnclosing}) { |
| 819 return compiler.backend.isAccessibleByReflection(element); | 841 return compiler.backend.isAccessibleByReflection(element); |
| 820 } | 842 } |
| 821 | 843 |
| 822 void internalAddToWorkList(Element element) { | 844 bool internalAddToWorkList(Element element) { |
| 823 if (compiler.hasIncrementalSupport) { | 845 if (compiler.hasIncrementalSupport) { |
| 824 newlyEnqueuedElements.add(element); | 846 newlyEnqueuedElements.add(element); |
| 825 } | 847 } |
| 826 // Don't generate code for foreign elements. | 848 // Don't generate code for foreign elements. |
| 827 if (element.isForeign(compiler)) return; | 849 if (element.isForeign(compiler)) return false; |
| 828 | 850 |
| 829 // Codegen inlines field initializers. It only needs to generate | 851 // Codegen inlines field initializers. It only needs to generate |
| 830 // code for checked setters. | 852 // code for checked setters. |
| 831 if (element.isField && element.isInstanceMember) { | 853 if (element.isField && element.isInstanceMember) { |
| 832 if (!compiler.enableTypeAssertions | 854 if (!compiler.enableTypeAssertions |
| 833 || element.enclosingElement.isClosure) { | 855 || element.enclosingElement.isClosure) { |
| 834 return; | 856 return false; |
| 835 } | 857 } |
| 836 } | 858 } |
| 837 | 859 |
| 838 if (queueIsClosed) { | 860 if (queueIsClosed) { |
| 839 throw new SpannableAssertionFailure(element, | 861 throw new SpannableAssertionFailure(element, |
| 840 "Codegen work list is closed. Trying to add $element"); | 862 "Codegen work list is closed. Trying to add $element"); |
| 841 } | 863 } |
| 842 CodegenWorkItem workItem = new CodegenWorkItem( | 864 CodegenWorkItem workItem = new CodegenWorkItem( |
| 843 element, itemCompilationContextCreator()); | 865 element, itemCompilationContextCreator()); |
| 844 queue.add(workItem); | 866 queue.add(workItem); |
| 867 return true; |
| 845 } | 868 } |
| 846 | 869 |
| 847 void _logSpecificSummary(log(message)) { | 870 void _logSpecificSummary(log(message)) { |
| 848 log('Compiled ${generatedCode.length} methods.'); | 871 log('Compiled ${generatedCode.length} methods.'); |
| 849 } | 872 } |
| 850 } | 873 } |
| 851 | 874 |
| 852 /// Parameterizes filtering of which work items are enqueued. | 875 /// Parameterizes filtering of which work items are enqueued. |
| 853 class QueueFilter { | 876 class QueueFilter { |
| 854 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { | 877 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { |
| 855 enqueuer.task.measure(() { | 878 enqueuer.task.measure(() { |
| 856 // Run through the classes and see if we need to compile methods. | 879 // Run through the classes and see if we need to compile methods. |
| 857 for (ClassElement classElement in enqueuer.universe.instantiatedClasses) { | 880 for (ClassElement classElement in enqueuer.universe.instantiatedClasses) { |
| 858 for (ClassElement currentClass = classElement; | 881 for (ClassElement currentClass = classElement; |
| 859 currentClass != null; | 882 currentClass != null; |
| 860 currentClass = currentClass.superclass) { | 883 currentClass = currentClass.superclass) { |
| 861 enqueuer.processInstantiatedClass(currentClass); | 884 enqueuer.processInstantiatedClass(currentClass); |
| 862 } | 885 } |
| 863 } | 886 } |
| 864 }); | 887 }); |
| 865 return true; | 888 return true; |
| 866 } | 889 } |
| 867 | 890 |
| 868 void processWorkItem(void f(WorkItem work), WorkItem work) { | 891 void processWorkItem(void f(WorkItem work), WorkItem work) { |
| 869 f(work); | 892 f(work); |
| 870 } | 893 } |
| 871 } | 894 } |
| OLD | NEW |