Chromium Code Reviews| 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 class EnqueueTask extends CompilerTask { | 7 class EnqueueTask extends CompilerTask { |
| 8 final ResolutionEnqueuer resolution; | 8 final ResolutionEnqueuer resolution; |
| 9 final CodegenEnqueuer codegen; | 9 final CodegenEnqueuer codegen; |
| 10 | 10 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 bool get isResolutionQueue => false; | 104 bool get isResolutionQueue => false; |
| 105 | 105 |
| 106 /// Returns [:true:] if [member] has been processed by this enqueuer. | 106 /// Returns [:true:] if [member] has been processed by this enqueuer. |
| 107 bool isProcessed(Element member); | 107 bool isProcessed(Element member); |
| 108 | 108 |
| 109 /** | 109 /** |
| 110 * Documentation wanted -- johnniwinther | 110 * Documentation wanted -- johnniwinther |
| 111 * | 111 * |
| 112 * Invariant: [element] must be a declaration element. | 112 * Invariant: [element] must be a declaration element. |
| 113 */ | 113 */ |
| 114 void addToWorkList(Element element, [TreeElements elements]) { | 114 void addToWorkList(Element element) { |
| 115 assert(invariant(element, element.isDeclaration)); | 115 assert(invariant(element, element.isDeclaration)); |
| 116 if (element.isForeign(compiler)) return; | 116 if (element.isForeign(compiler)) return; |
| 117 | 117 |
| 118 if (element.isForwardingConstructor) { | 118 if (element.isForwardingConstructor) { |
| 119 addToWorkList(element.targetConstructor, elements); | 119 addToWorkList(element.targetConstructor); |
| 120 return; | 120 return; |
| 121 } | 121 } |
| 122 | 122 |
| 123 if (!addElementToWorkList(element, elements)) return; | 123 addElementToWorkList(element); |
| 124 | |
| 125 // Enable runtime type support if we discover a getter called runtimeType. | |
| 126 // We have to enable runtime type before hitting the codegen, so | |
| 127 // that constructors know whether they need to generate code for | |
| 128 // runtime type. | |
| 129 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) { | |
| 130 compiler.enabledRuntimeType = true; | |
| 131 // TODO(ahe): Record precise dependency here. | |
| 132 compiler.backend.registerRuntimeType(compiler.globalDependencies); | |
| 133 } else if (element == compiler.functionApplyMethod) { | |
| 134 compiler.enabledFunctionApply = true; | |
| 135 } else if (element == compiler.invokeOnMethod) { | |
| 136 compiler.enabledInvokeOn = true; | |
| 137 } | |
| 138 | |
| 139 nativeEnqueuer.registerElement(element); | |
| 140 } | 124 } |
| 141 | 125 |
| 142 /** | 126 /** |
| 143 * Adds [element] to the work list if it has not already been processed. | 127 * Adds [element] to the work list if it has not already been processed. |
| 144 * | |
| 145 * Returns [:true:] if the [element] should be processed. | |
| 146 */ | 128 */ |
| 147 // TODO(johnniwinther): Change to 'Returns true if the element was added to | 129 void addElementToWorkList(Element element); |
|
ahe
2013/06/11 08:56:20
I think it would be a great time to rename either
ngeoffray
2013/06/11 09:05:14
Done.
| |
| 148 // the work list'? | |
| 149 bool addElementToWorkList(Element element, [TreeElements elements]); | |
| 150 | 130 |
| 151 void registerInstantiatedType(InterfaceType type, TreeElements elements) { | 131 void registerInstantiatedType(InterfaceType type, TreeElements elements) { |
| 152 ClassElement cls = type.element; | 132 ClassElement cls = type.element; |
| 153 elements.registerDependency(cls); | 133 elements.registerDependency(cls); |
| 154 cls.ensureResolved(compiler); | 134 cls.ensureResolved(compiler); |
| 155 universe.instantiatedTypes.add(type); | 135 universe.instantiatedTypes.add(type); |
| 156 if (universe.instantiatedClasses.contains(cls)) return; | 136 if (universe.instantiatedClasses.contains(cls)) return; |
| 157 if (!cls.isAbstract(compiler)) { | 137 if (!cls.isAbstract(compiler)) { |
| 158 universe.instantiatedClasses.add(cls); | 138 universe.instantiatedClasses.add(cls); |
| 159 } | 139 } |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 600 ItemCompilationContext itemCompilationContextCreator()) | 580 ItemCompilationContext itemCompilationContextCreator()) |
| 601 : super('resolution enqueuer', compiler, itemCompilationContextCreator), | 581 : super('resolution enqueuer', compiler, itemCompilationContextCreator), |
| 602 resolvedElements = new Map<Element, TreeElements>(), | 582 resolvedElements = new Map<Element, TreeElements>(), |
| 603 queue = new Queue<ResolutionWorkItem>(), | 583 queue = new Queue<ResolutionWorkItem>(), |
| 604 postQueue = new Queue<PostProcessTask>(); | 584 postQueue = new Queue<PostProcessTask>(); |
| 605 | 585 |
| 606 bool get isResolutionQueue => true; | 586 bool get isResolutionQueue => true; |
| 607 | 587 |
| 608 bool isProcessed(Element member) => resolvedElements.containsKey(member); | 588 bool isProcessed(Element member) => resolvedElements.containsKey(member); |
| 609 | 589 |
| 610 TreeElements getCachedElements(Element element) { | 590 TreeElements getCachedElements(element) { |
|
ahe
2013/06/11 08:56:20
Why remove the type annotation here?
ngeoffray
2013/06/11 09:05:14
Because I'm using the 'constructor' field and that
| |
| 611 // TODO(ngeoffray): Get rid of this check. | 591 // TODO(ngeoffray): Get rid of this check. |
| 612 if (element.enclosingElement.isClosure()) { | 592 if (element.enclosingElement.isClosure()) { |
| 613 closureMapping.ClosureClassElement cls = element.enclosingElement; | 593 closureMapping.ClosureClassElement cls = element.enclosingElement; |
| 614 element = cls.methodElement; | 594 element = cls.methodElement; |
| 595 } else if (element.isGenerativeConstructorBody()) { | |
| 596 element = element.constructor; | |
| 615 } | 597 } |
| 616 Element owner = element.getOutermostEnclosingMemberOrTopLevel(); | 598 Element owner = element.getOutermostEnclosingMemberOrTopLevel(); |
| 617 if (owner == null) { | 599 if (owner == null) { |
| 618 owner = element; | 600 owner = element; |
| 619 } | 601 } |
| 620 return resolvedElements[owner.declaration]; | 602 return resolvedElements[owner.declaration]; |
| 621 } | 603 } |
| 622 | 604 |
| 623 /** | 605 bool addElementToWorkList(Element element) { |
| 624 * Sets the resolved elements of [element] to [elements], or if [elements] is | 606 if (getCachedElements(element) != null) return; |
| 625 * [:null:], to the elements found through [getCachedElements]. | |
| 626 * | |
| 627 * Returns the resolved elements. | |
| 628 */ | |
| 629 TreeElements ensureCachedElements(Element element, TreeElements elements) { | |
| 630 if (elements == null) { | |
| 631 elements = getCachedElements(element); | |
| 632 } | |
| 633 resolvedElements[element] = elements; | |
| 634 return elements; | |
| 635 } | |
| 636 | |
| 637 bool addElementToWorkList(Element element, [TreeElements elements]) { | |
| 638 if (queueIsClosed) { | 607 if (queueIsClosed) { |
| 639 if (getCachedElements(element) != null) return false; | |
| 640 throw new SpannableAssertionFailure(element, | 608 throw new SpannableAssertionFailure(element, |
| 641 "Resolution work list is closed."); | 609 "Resolution work list is closed."); |
| 642 } | 610 } |
| 643 if (elements == null) { | |
| 644 elements = getCachedElements(element); | |
| 645 } | |
| 646 compiler.world.registerUsedElement(element); | 611 compiler.world.registerUsedElement(element); |
| 647 | 612 |
| 648 if (elements == null) { | 613 queue.add(new ResolutionWorkItem(element, itemCompilationContextCreator())); |
| 649 queue.add( | |
| 650 new ResolutionWorkItem(element, itemCompilationContextCreator())); | |
| 651 } | |
| 652 | 614 |
| 653 // Enable isolate support if we start using something from the | 615 // Enable isolate support if we start using something from the |
| 654 // isolate library, or timers for the async library. | 616 // isolate library, or timers for the async library. |
| 655 LibraryElement library = element.getLibrary(); | 617 LibraryElement library = element.getLibrary(); |
| 656 if (!compiler.hasIsolateSupport()) { | 618 if (!compiler.hasIsolateSupport()) { |
| 657 String uri = library.canonicalUri.toString(); | 619 String uri = library.canonicalUri.toString(); |
| 658 if (uri == 'dart:isolate') { | 620 if (uri == 'dart:isolate') { |
| 659 enableIsolateSupport(library); | 621 enableIsolateSupport(library); |
| 660 } else if (uri == 'dart:async') { | 622 } else if (uri == 'dart:async') { |
| 661 ClassElement cls = element.getEnclosingClass(); | 623 ClassElement cls = element.getEnclosingClass(); |
| 662 if (cls != null && cls.name == const SourceString('Timer')) { | 624 if (cls != null && cls.name == const SourceString('Timer')) { |
| 663 // The [:Timer:] class uses the event queue of the isolate | 625 // The [:Timer:] class uses the event queue of the isolate |
| 664 // library, so we make sure that event queue is generated. | 626 // library, so we make sure that event queue is generated. |
| 665 enableIsolateSupport(library); | 627 enableIsolateSupport(library); |
| 666 } | 628 } |
| 667 } | 629 } |
| 668 } | 630 } |
| 669 | 631 |
| 670 return true; | 632 // Enable runtime type support if we discover a getter called runtimeType. |
|
ahe
2013/06/11 08:56:20
This comment is out of date, more cases have been
ngeoffray
2013/06/11 09:05:14
Done.
| |
| 633 // We have to enable runtime type before hitting the codegen, so | |
| 634 // that constructors know whether they need to generate code for | |
| 635 // runtime type. | |
| 636 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) { | |
| 637 compiler.enabledRuntimeType = true; | |
| 638 // TODO(ahe): Record precise dependency here. | |
| 639 compiler.backend.registerRuntimeType(compiler.globalDependencies); | |
| 640 } else if (element == compiler.functionApplyMethod) { | |
| 641 compiler.enabledFunctionApply = true; | |
| 642 } else if (element == compiler.invokeOnMethod) { | |
| 643 compiler.enabledInvokeOn = true; | |
| 644 } | |
| 645 | |
| 646 nativeEnqueuer.registerElement(element); | |
| 647 return; | |
|
ahe
2013/06/11 08:56:20
Remove return.
ngeoffray
2013/06/11 09:05:14
Done.
| |
| 671 } | 648 } |
| 672 | 649 |
| 673 void enableIsolateSupport(LibraryElement element) { | 650 void enableIsolateSupport(LibraryElement element) { |
| 674 compiler.isolateLibrary = element.patch; | 651 compiler.isolateLibrary = element.patch; |
| 675 var startRootIsolate = | 652 var startRootIsolate = |
| 676 compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE); | 653 compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE); |
| 677 addToWorkList(startRootIsolate); | 654 addToWorkList(startRootIsolate); |
| 678 compiler.globalDependencies.registerDependency(startRootIsolate); | 655 compiler.globalDependencies.registerDependency(startRootIsolate); |
| 679 addToWorkList(compiler.isolateHelperLibrary.find( | 656 addToWorkList(compiler.isolateHelperLibrary.find( |
| 680 const SourceString('_currentIsolate'))); | 657 const SourceString('_currentIsolate'))); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 739 new Map<Element, js.Expression>(); | 716 new Map<Element, js.Expression>(); |
| 740 | 717 |
| 741 CodegenEnqueuer(Compiler compiler, | 718 CodegenEnqueuer(Compiler compiler, |
| 742 ItemCompilationContext itemCompilationContextCreator()) | 719 ItemCompilationContext itemCompilationContextCreator()) |
| 743 : super('codegen enqueuer', compiler, itemCompilationContextCreator), | 720 : super('codegen enqueuer', compiler, itemCompilationContextCreator), |
| 744 queue = new Queue<CodegenWorkItem>(); | 721 queue = new Queue<CodegenWorkItem>(); |
| 745 | 722 |
| 746 bool isProcessed(Element member) => | 723 bool isProcessed(Element member) => |
| 747 member.isAbstract(compiler) || generatedCode.containsKey(member); | 724 member.isAbstract(compiler) || generatedCode.containsKey(member); |
| 748 | 725 |
| 749 bool addElementToWorkList(Element element, [TreeElements elements]) { | 726 bool addElementToWorkList(Element element) { |
| 750 // Codegen inlines field initializers, so it does not need to add | 727 // Codegen inlines field initializers, so it does not need to add |
| 751 // individual fields in the work list. | 728 // individual fields in the work list. |
| 752 if (element.isField() && element.isInstanceMember()) return true; | 729 if (element.isField() && element.isInstanceMember()) return; |
| 753 | 730 |
| 754 if (queueIsClosed) { | 731 if (queueIsClosed) { |
| 755 throw new SpannableAssertionFailure(element, | 732 throw new SpannableAssertionFailure(element, |
| 756 "Codegen work list is closed."); | 733 "Codegen work list is closed."); |
| 757 } | 734 } |
| 758 elements = | |
| 759 compiler.enqueuer.resolution.ensureCachedElements(element, elements); | |
| 760 | |
| 761 CodegenWorkItem workItem = new CodegenWorkItem( | 735 CodegenWorkItem workItem = new CodegenWorkItem( |
| 762 element, elements, itemCompilationContextCreator()); | 736 element, itemCompilationContextCreator()); |
| 763 queue.add(workItem); | 737 queue.add(workItem); |
| 764 | |
| 765 return true; | |
| 766 } | 738 } |
| 767 | 739 |
| 768 void forEach(f(WorkItem work)) { | 740 void forEach(f(WorkItem work)) { |
| 769 while(!queue.isEmpty) { | 741 while(!queue.isEmpty) { |
| 770 // TODO(johnniwinther): Find an optimal process order for codegen. | 742 // TODO(johnniwinther): Find an optimal process order for codegen. |
| 771 f(queue.removeLast()); | 743 f(queue.removeLast()); |
| 772 } | 744 } |
| 773 } | 745 } |
| 774 | 746 |
| 775 void _logSpecificSummary(log(message)) { | 747 void _logSpecificSummary(log(message)) { |
| 776 log('Compiled ${generatedCode.length} methods.'); | 748 log('Compiled ${generatedCode.length} methods.'); |
| 777 } | 749 } |
| 778 } | 750 } |
| OLD | NEW |