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 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 Loading... | |
| 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; | |
|
kasperl
2013/01/24 09:03:51
One option would be to use a SelectorMap and make
| |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1190 } | 1198 } |
| 1191 | 1199 |
| 1192 Element getSetRuntimeTypeInfo() { | 1200 Element getSetRuntimeTypeInfo() { |
| 1193 return compiler.findHelper(const SourceString('setRuntimeTypeInfo')); | 1201 return compiler.findHelper(const SourceString('setRuntimeTypeInfo')); |
| 1194 } | 1202 } |
| 1195 | 1203 |
| 1196 Element getGetRuntimeTypeInfo() { | 1204 Element getGetRuntimeTypeInfo() { |
| 1197 return compiler.findHelper(const SourceString('getRuntimeTypeInfo')); | 1205 return compiler.findHelper(const SourceString('getRuntimeTypeInfo')); |
| 1198 } | 1206 } |
| 1199 } | 1207 } |
| OLD | NEW |