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

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

Issue 12033056: Implement "one-shot" interceptors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 FieldTypesRegistry fieldTypes; 661 FieldTypesRegistry fieldTypes;
662 662
663 /** 663 /**
664 * A collection of selectors of intercepted method calls. The 664 * A collection of selectors of intercepted method calls. The
665 * emitter uses this set to generate the [:ObjectInterceptor:] class 665 * emitter uses this set to generate the [:ObjectInterceptor:] class
666 * whose members just forward the call to the intercepted receiver. 666 * whose members just forward the call to the intercepted receiver.
667 */ 667 */
668 final Set<Selector> usedInterceptors; 668 final Set<Selector> usedInterceptors;
669 669
670 /** 670 /**
671 * A collection of selectors that must have a one shot interceptor
672 * generated.
673 */
674 final Set<Selector> oneShotInterceptors;
675
676 /**
671 * The members of instantiated interceptor classes: maps a member 677 * The members of instantiated interceptor classes: maps a member
672 * name to the list of members that have that name. This map is used 678 * name to the list of members that have that name. This map is used
673 * by the codegen to know whether a send must be intercepted or not. 679 * by the codegen to know whether a send must be intercepted or not.
674 */ 680 */
675 final Map<SourceString, Set<Element>> interceptedElements; 681 final Map<SourceString, Set<Element>> interceptedElements;
676 682
677 /** 683 /**
678 * A map of specialized versions of the [getInterceptorMethod]. 684 * A map of specialized versions of the [getInterceptorMethod].
679 * Since [getInterceptorMethod] is a hot method at runtime, we're 685 * Since [getInterceptorMethod] is a hot method at runtime, we're
680 * always specializing it based on the incoming type. The keys in 686 * always specializing it based on the incoming type. The keys in
(...skipping 14 matching lines...) Expand all
695 return <CompilerTask>[builder, optimizer, generator, emitter]; 701 return <CompilerTask>[builder, optimizer, generator, emitter];
696 } 702 }
697 703
698 final RuntimeTypeInformation rti; 704 final RuntimeTypeInformation rti;
699 705
700 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval) 706 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval)
701 : namer = determineNamer(compiler), 707 : namer = determineNamer(compiler),
702 returnInfo = new Map<Element, ReturnInfo>(), 708 returnInfo = new Map<Element, ReturnInfo>(),
703 invalidateAfterCodegen = new List<Element>(), 709 invalidateAfterCodegen = new List<Element>(),
704 usedInterceptors = new Set<Selector>(), 710 usedInterceptors = new Set<Selector>(),
711 oneShotInterceptors = new Set<Selector>(),
705 interceptedElements = new Map<SourceString, Set<Element>>(), 712 interceptedElements = new Map<SourceString, Set<Element>>(),
706 rti = new RuntimeTypeInformation(compiler), 713 rti = new RuntimeTypeInformation(compiler),
707 specializedGetInterceptors = 714 specializedGetInterceptors =
708 new Map<String, Collection<ClassElement>>(), 715 new Map<String, Collection<ClassElement>>(),
709 interceptedClasses = new LinkedHashMap<ClassElement, ClassElement>(), 716 interceptedClasses = new LinkedHashMap<ClassElement, ClassElement>(),
710 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { 717 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) {
711 emitter = disableEval 718 emitter = disableEval
712 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap) 719 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap)
713 : new CodeEmitterTask(compiler, namer, generateSourceMap); 720 : new CodeEmitterTask(compiler, namer, generateSourceMap);
714 builder = new SsaBuilderTask(this); 721 builder = new SsaBuilderTask(this);
(...skipping 11 matching lines...) Expand all
726 733
727 bool isInterceptorClass(Element element) { 734 bool isInterceptorClass(Element element) {
728 if (element == null) return false; 735 if (element == null) return false;
729 return interceptedClasses.containsKey(element); 736 return interceptedClasses.containsKey(element);
730 } 737 }
731 738
732 void addInterceptedSelector(Selector selector) { 739 void addInterceptedSelector(Selector selector) {
733 usedInterceptors.add(selector); 740 usedInterceptors.add(selector);
734 } 741 }
735 742
743 void addOneShotInterceptor(Selector selector) {
744 oneShotInterceptors.add(selector);
745 }
746
736 /** 747 /**
737 * Returns a set of interceptor classes that contain a member whose 748 * Returns a set of interceptor classes that contain a member whose
738 * signature matches the given [selector]. Returns [:null:] if there 749 * signature matches the given [selector]. Returns [:null:] if there
739 * is no class. 750 * is no class.
740 */ 751 */
741 Set<ClassElement> getInterceptedClassesOn(Selector selector) { 752 Set<ClassElement> getInterceptedClassesOn(Selector selector) {
742 Set<Element> intercepted = interceptedElements[selector.name]; 753 Set<Element> intercepted = interceptedElements[selector.name];
743 if (intercepted == null) return null; 754 if (intercepted == null) return null;
744 Set<ClassElement> result = new Set<ClassElement>(); 755 Set<ClassElement> result = new Set<ClassElement>();
745 for (Element element in intercepted) { 756 for (Element element in intercepted) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 cls.forEachMember((ClassElement classElement, Element member) { 813 cls.forEachMember((ClassElement classElement, Element member) {
803 Set<Element> set = interceptedElements.putIfAbsent( 814 Set<Element> set = interceptedElements.putIfAbsent(
804 member.name, () => new Set<Element>()); 815 member.name, () => new Set<Element>());
805 set.add(member); 816 set.add(member);
806 }, 817 },
807 includeSuperMembers: true); 818 includeSuperMembers: true);
808 } 819 }
809 enqueuer.registerInstantiatedClass(cls); 820 enqueuer.registerInstantiatedClass(cls);
810 } 821 }
811 822
812 String registerSpecializedGetInterceptor(Set<ClassElement> classes) { 823 void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
813 compiler.enqueuer.codegen.registerInstantiatedClass(objectInterceptorClass); 824 compiler.enqueuer.codegen.registerInstantiatedClass(objectInterceptorClass);
825 String name = namer.getInterceptorName(getInterceptorMethod, classes);
814 if (classes.contains(compiler.objectClass)) { 826 if (classes.contains(compiler.objectClass)) {
815 // We can't use a specialized [getInterceptorMethod], so we make 827 // We can't use a specialized [getInterceptorMethod], so we make
816 // sure we emit the one with all checks. 828 // sure we emit the one with all checks.
817 String name = namer.getName(getInterceptorMethod);
818 specializedGetInterceptors.putIfAbsent(name, () { 829 specializedGetInterceptors.putIfAbsent(name, () {
819 // It is important to take the order provided by the map, 830 // It is important to take the order provided by the map,
820 // because we want the int type check to happen before the 831 // because we want the int type check to happen before the
821 // double type check: the double type check covers the int 832 // double type check: the double type check covers the int
822 // type check. Also we don't need to do a number type check 833 // type check. Also we don't need to do a number type check
823 // because that is covered by the double type check. 834 // because that is covered by the double type check.
824 List<ClassElement> keys = <ClassElement>[]; 835 List<ClassElement> keys = <ClassElement>[];
825 interceptedClasses.forEach((ClassElement cls, _) { 836 interceptedClasses.forEach((ClassElement cls, _) {
826 if (cls != jsNumberClass) keys.add(cls); 837 if (cls != jsNumberClass) keys.add(cls);
827 }); 838 });
828 return keys; 839 return keys;
829 }); 840 });
830 return namer.isolateAccess(getInterceptorMethod);
831 } else { 841 } else {
832 String name = namer.getSpecializedName(getInterceptorMethod, classes);
833 specializedGetInterceptors[name] = classes; 842 specializedGetInterceptors[name] = classes;
834 return '${namer.CURRENT_ISOLATE}.$name';
835 } 843 }
836 } 844 }
837 845
838 void initializeNoSuchMethod() { 846 void initializeNoSuchMethod() {
839 // In case the emitter generates noSuchMethod calls, we need to 847 // In case the emitter generates noSuchMethod calls, we need to
840 // make sure all [noSuchMethod] methods know they might take a 848 // make sure all [noSuchMethod] methods know they might take a
841 // [JsInvocationMirror] as parameter. 849 // [JsInvocationMirror] as parameter.
842 HTypeList types = new HTypeList(1); 850 HTypeList types = new HTypeList(1);
843 types[0] = new HType.fromBoundedType( 851 types[0] = new HType.fromBoundedType(
844 compiler.jsInvocationMirrorClass.computeType(compiler), 852 compiler.jsInvocationMirrorClass.computeType(compiler),
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 } 1197 }
1190 1198
1191 Element getSetRuntimeTypeInfo() { 1199 Element getSetRuntimeTypeInfo() {
1192 return compiler.findHelper(const SourceString('setRuntimeTypeInfo')); 1200 return compiler.findHelper(const SourceString('setRuntimeTypeInfo'));
1193 } 1201 }
1194 1202
1195 Element getGetRuntimeTypeInfo() { 1203 Element getGetRuntimeTypeInfo() {
1196 return compiler.findHelper(const SourceString('getRuntimeTypeInfo')); 1204 return compiler.findHelper(const SourceString('getRuntimeTypeInfo'));
1197 } 1205 }
1198 } 1206 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698