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

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

Issue 11348177: Cleanup after the interceptor refactoring work, and add a new SSA instruction for an interceptor, s… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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 js_backend; 5 part of js_backend;
6 6
7 typedef void Recompile(Element element); 7 typedef void Recompile(Element element);
8 8
9 class ReturnInfo { 9 class ReturnInfo {
10 HType returnType; 10 HType returnType;
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 * emitter uses this set to generate the [:ObjectInterceptor:] class 688 * emitter uses this set to generate the [:ObjectInterceptor:] class
689 * whose members just forward the call to the intercepted receiver. 689 * whose members just forward the call to the intercepted receiver.
690 */ 690 */
691 final Set<Selector> usedInterceptors; 691 final Set<Selector> usedInterceptors;
692 692
693 /** 693 /**
694 * The members of instantiated interceptor classes: maps a member 694 * The members of instantiated interceptor classes: maps a member
695 * name to the list of members that have that name. This map is used 695 * name to the list of members that have that name. This map is used
696 * by the codegen to know whether a send must be intercepted or not. 696 * by the codegen to know whether a send must be intercepted or not.
697 */ 697 */
698 final Map<SourceString, List<Element>> interceptedElements; 698 final Map<SourceString, Set<Element>> interceptedElements;
699 699
700 List<CompilerTask> get tasks { 700 List<CompilerTask> get tasks {
701 return <CompilerTask>[builder, optimizer, generator, emitter]; 701 return <CompilerTask>[builder, optimizer, generator, emitter];
702 } 702 }
703 703
704 final RuntimeTypeInformation rti; 704 final RuntimeTypeInformation rti;
705 705
706 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval) 706 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval)
707 : namer = determineNamer(compiler), 707 : namer = determineNamer(compiler),
708 returnInfo = new Map<Element, ReturnInfo>(), 708 returnInfo = new Map<Element, ReturnInfo>(),
709 invalidateAfterCodegen = new List<Element>(), 709 invalidateAfterCodegen = new List<Element>(),
710 interceptors = new Interceptors(compiler), 710 interceptors = new Interceptors(compiler),
711 usedInterceptors = new Set<Selector>(), 711 usedInterceptors = new Set<Selector>(),
712 interceptedElements = new Map<SourceString, List<Element>>(), 712 interceptedElements = new Map<SourceString, Set<Element>>(),
713 rti = new RuntimeTypeInformation(compiler), 713 rti = new RuntimeTypeInformation(compiler),
714 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { 714 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) {
715 emitter = disableEval 715 emitter = disableEval
716 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap) 716 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap)
717 : new CodeEmitterTask(compiler, namer, generateSourceMap); 717 : new CodeEmitterTask(compiler, namer, generateSourceMap);
718 builder = new SsaBuilderTask(this); 718 builder = new SsaBuilderTask(this);
719 optimizer = new SsaOptimizerTask(this); 719 optimizer = new SsaOptimizerTask(this);
720 generator = new SsaCodeGeneratorTask(this); 720 generator = new SsaCodeGeneratorTask(this);
721 argumentTypes = new ArgumentTypesRegistry(this); 721 argumentTypes = new ArgumentTypesRegistry(this);
722 fieldTypes = new FieldTypesRegistry(this); 722 fieldTypes = new FieldTypesRegistry(this);
(...skipping 14 matching lines...) Expand all
737 || element == jsNullClass 737 || element == jsNullClass
738 || element == jsFunctionClass 738 || element == jsFunctionClass
739 || element == jsBoolClass 739 || element == jsBoolClass
740 || element == jsNumberClass; 740 || element == jsNumberClass;
741 } 741 }
742 742
743 void addInterceptedSelector(Selector selector) { 743 void addInterceptedSelector(Selector selector) {
744 usedInterceptors.add(selector); 744 usedInterceptors.add(selector);
745 } 745 }
746 746
747 bool shouldInterceptSelector(Selector selector) { 747 /**
748 List<Element> intercepted = interceptedElements[selector.name]; 748 * Returns a set of interceptor classes that contain a member whose
749 if (intercepted == null) return false; 749 * signature matches the given [selector]. Returns [:null:] if there
750 * is no class.
751 */
752 Set<ClassElement> getInterceptedClassesOn(Selector selector) {
ahe 2012/11/22 13:26:11 How about computing the reverse mapping? This see
ngeoffray 2012/11/22 13:37:59 As discussed, we already have the reverse mapping,
753 Set<Element> intercepted = interceptedElements[selector.name];
754 if (intercepted == null) return null;
755 Set<ClassElement> result = new Set<ClassElement>();
750 for (Element element in intercepted) { 756 for (Element element in intercepted) {
751 if (selector.applies(element, compiler)) return true; 757 if (selector.applies(element, compiler)) {
758 result.add(element.getEnclosingClass());
759 }
752 } 760 }
753 return false; 761 if (result.isEmpty) return null;
762 return result;
754 } 763 }
755 764
756 void initializeInterceptorElements() { 765 void initializeInterceptorElements() {
757 objectInterceptorClass = 766 objectInterceptorClass =
758 compiler.findInterceptor(const SourceString('ObjectInterceptor')); 767 compiler.findInterceptor(const SourceString('ObjectInterceptor'));
759 getInterceptorMethod = 768 getInterceptorMethod =
760 compiler.findInterceptor(const SourceString('getInterceptor')); 769 compiler.findInterceptor(const SourceString('getInterceptor'));
761 jsStringClass = 770 jsStringClass =
762 compiler.findInterceptor(const SourceString('JSString')); 771 compiler.findInterceptor(const SourceString('JSString'));
763 jsArrayClass = 772 jsArrayClass =
(...skipping 16 matching lines...) Expand all
780 jsStringClass.ensureResolved(compiler); 789 jsStringClass.ensureResolved(compiler);
781 jsStringLength = 790 jsStringLength =
782 jsStringClass.lookupLocalMember(const SourceString('length')); 791 jsStringClass.lookupLocalMember(const SourceString('length'));
783 listImplementation = 792 listImplementation =
784 compiler.coreLibrary.find(const SourceString('ListImplementation')); 793 compiler.coreLibrary.find(const SourceString('ListImplementation'));
785 } 794 }
786 795
787 void addInterceptors(ClassElement cls) { 796 void addInterceptors(ClassElement cls) {
788 cls.ensureResolved(compiler); 797 cls.ensureResolved(compiler);
789 cls.forEachMember((ClassElement classElement, Element member) { 798 cls.forEachMember((ClassElement classElement, Element member) {
790 // TODO(ngeoffray): Support interceptors on Object methods. 799 Set<Element> set = interceptedElements.putIfAbsent(
791 if (classElement == compiler.objectClass) return; 800 member.name, () => new Set<Element>());
792 List<Element> list = interceptedElements.putIfAbsent( 801 set.add(member);
793 member.name, () => new List<Element>()); 802 },
794 list.add(member); 803 includeSuperMembers: true);
795 }, includeSuperMembers: true);
796 } 804 }
797 805
798 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) { 806 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {
799 ClassElement result = null; 807 ClassElement result = null;
800 if (!_interceptorsAreInitialized) { 808 if (!_interceptorsAreInitialized) {
801 initializeInterceptorElements(); 809 initializeInterceptorElements();
802 _interceptorsAreInitialized = true; 810 _interceptorsAreInitialized = true;
803 // The null interceptor and the function interceptor are 811 // The null interceptor and the function interceptor are
804 // currently always instantiated if a new class is instantiated. 812 // currently always instantiated if a new class is instantiated.
805 // TODO(ngeoffray): do this elsewhere for the function 813 // TODO(ngeoffray): do this elsewhere for the function
806 // interceptor? 814 // interceptor?
807 if (jsNullClass != null) { 815 if (jsNullClass != null) {
808 addInterceptors(jsNullClass); 816 addInterceptors(jsNullClass);
809 enqueuer.registerInstantiatedClass(jsNullClass); 817 enqueuer.registerInstantiatedClass(jsNullClass);
810 } 818 }
811 if (jsFunctionClass != null) { 819 if (jsFunctionClass != null) {
812 addInterceptors(jsFunctionClass); 820 addInterceptors(jsFunctionClass);
813 enqueuer.registerInstantiatedClass(jsFunctionClass); 821 enqueuer.registerInstantiatedClass(jsFunctionClass);
814 } 822 }
823 enqueuer.addToWorkList(getInterceptorMethod);
815 } 824 }
816 if (cls == compiler.stringClass) { 825 if (cls == compiler.stringClass) {
817 result = jsStringClass; 826 result = jsStringClass;
818 } else if (cls == compiler.listClass || cls == listImplementation) { 827 } else if (cls == compiler.listClass || cls == listImplementation) {
819 result = jsArrayClass; 828 result = jsArrayClass;
820 } else if (cls == compiler.intClass) { 829 } else if (cls == compiler.intClass) {
821 result = jsIntClass; 830 result = jsIntClass;
822 } else if (cls == compiler.doubleClass) { 831 } else if (cls == compiler.doubleClass) {
823 result = jsDoubleClass; 832 result = jsDoubleClass;
824 } else if (cls == compiler.functionClass) { 833 } else if (cls == compiler.functionClass) {
825 result = jsFunctionClass; 834 result = jsFunctionClass;
826 } else if (cls == compiler.boolClass) { 835 } else if (cls == compiler.boolClass) {
827 result = jsBoolClass; 836 result = jsBoolClass;
828 } 837 }
829 838
830 if (result == null) return; 839 if (result == null) return;
831 if (enqueuer.isResolutionQueue) addInterceptors(result); 840 if (enqueuer.isResolutionQueue) addInterceptors(result);
832 enqueuer.registerInstantiatedClass(result); 841 enqueuer.registerInstantiatedClass(result);
833 } 842 }
834 843
835 Element get cyclicThrowHelper { 844 Element get cyclicThrowHelper {
836 return compiler.findHelper(const SourceString("throwCyclicInit")); 845 return compiler.findHelper(const SourceString("throwCyclicInit"));
837 } 846 }
838 847
839 JavaScriptItemCompilationContext createItemCompilationContext() { 848 JavaScriptItemCompilationContext createItemCompilationContext() {
840 return new JavaScriptItemCompilationContext(); 849 return new JavaScriptItemCompilationContext();
841 } 850 }
842 851
843 Element getInterceptor(Selector selector) {
844 return interceptors.getStaticInterceptor(selector);
845 }
846
847 void enqueueHelpers(Enqueuer world) { 852 void enqueueHelpers(Enqueuer world) {
848 enqueueAllTopLevelFunctions(compiler.jsHelperLibrary, world); 853 enqueueAllTopLevelFunctions(compiler.jsHelperLibrary, world);
849 854
850 jsIndexingBehaviorInterface = 855 jsIndexingBehaviorInterface =
851 compiler.findHelper(const SourceString('JavaScriptIndexingBehavior')); 856 compiler.findHelper(const SourceString('JavaScriptIndexingBehavior'));
852 if (jsIndexingBehaviorInterface != null) { 857 if (jsIndexingBehaviorInterface != null) {
853 world.registerIsCheck(jsIndexingBehaviorInterface.computeType(compiler)); 858 world.registerIsCheck(jsIndexingBehaviorInterface.computeType(compiler));
854 } 859 }
855 860
856 for (var helper in [const SourceString('Closure'), 861 for (var helper in [const SourceString('Closure'),
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 print("Inferred return types:"); 1103 print("Inferred return types:");
1099 print("----------------------"); 1104 print("----------------------");
1100 dumpReturnTypes(); 1105 dumpReturnTypes();
1101 print(""); 1106 print("");
1102 print("Inferred field types:"); 1107 print("Inferred field types:");
1103 print("------------------------"); 1108 print("------------------------");
1104 fieldTypes.dump(); 1109 fieldTypes.dump();
1105 print(""); 1110 print("");
1106 } 1111 }
1107 } 1112 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698