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 const VERBOSE_OPTIMIZER_HINTS = false; | 7 const VERBOSE_OPTIMIZER_HINTS = false; |
8 | 8 |
9 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
(...skipping 2749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2760 break; | 2760 break; |
2761 case Feature.THROW_RUNTIME_ERROR: | 2761 case Feature.THROW_RUNTIME_ERROR: |
2762 registerBackendImpact(transformed, impacts.throwRuntimeError); | 2762 registerBackendImpact(transformed, impacts.throwRuntimeError); |
2763 break; | 2763 break; |
2764 case Feature.TYPE_VARIABLE_BOUNDS_CHECK: | 2764 case Feature.TYPE_VARIABLE_BOUNDS_CHECK: |
2765 registerBackendImpact(transformed, impacts.typeVariableBoundCheck); | 2765 registerBackendImpact(transformed, impacts.typeVariableBoundCheck); |
2766 break; | 2766 break; |
2767 } | 2767 } |
2768 } | 2768 } |
2769 | 2769 |
2770 for (InterfaceType type in worldImpact.instantiatedTypes) { | 2770 bool hasAsCast = false; |
2771 registerRequiredType(type); | 2771 bool hasTypeLiteral = false; |
| 2772 for (TypeUse typeUse in worldImpact.typeUses) { |
| 2773 DartType type = typeUse.type; |
| 2774 switch (typeUse.kind) { |
| 2775 case TypeUseKind.INSTANTIATION: |
| 2776 registerRequiredType(type); |
| 2777 break; |
| 2778 case TypeUseKind.IS_CHECK: |
| 2779 onIsCheck(type, transformed); |
| 2780 break; |
| 2781 case TypeUseKind.AS_CAST: |
| 2782 onIsCheck(type, transformed); |
| 2783 hasAsCast = true; |
| 2784 break; |
| 2785 case TypeUseKind.CHECKED_MODE_CHECK: |
| 2786 if (backend.compiler.enableTypeAssertions) { |
| 2787 onIsCheck(type, transformed); |
| 2788 } |
| 2789 break; |
| 2790 case TypeUseKind.CATCH_TYPE: |
| 2791 onIsCheck(type, transformed); |
| 2792 break; |
| 2793 case TypeUseKind.TYPE_LITERAL: |
| 2794 backend.customElementsAnalysis.registerTypeLiteral(type); |
| 2795 if (type.isTypedef) { |
| 2796 backend.compiler.world.allTypedefs.add(type.element); |
| 2797 } |
| 2798 if (type.isTypeVariable) { |
| 2799 ClassElement cls = type.element.enclosingClass; |
| 2800 backend.rti.registerClassUsingTypeVariableExpression(cls); |
| 2801 registerBackendImpact(transformed, impacts.typeVariableExpression); |
| 2802 } |
| 2803 hasTypeLiteral = true; |
| 2804 break; |
| 2805 } |
2772 } | 2806 } |
2773 | 2807 |
2774 for (DartType type in worldImpact.isChecks) { | 2808 if (hasAsCast) { |
2775 onIsCheck(type, transformed); | |
2776 } | |
2777 | |
2778 if (worldImpact.asCasts.isNotEmpty) { | |
2779 for (DartType type in worldImpact.asCasts) { | |
2780 onIsCheck(type, transformed); | |
2781 } | |
2782 registerBackendImpact(transformed, impacts.asCheck); | 2809 registerBackendImpact(transformed, impacts.asCheck); |
2783 } | 2810 } |
2784 | 2811 |
2785 if (backend.compiler.enableTypeAssertions) { | 2812 if (hasTypeLiteral) { |
2786 for (DartType type in worldImpact.checkedModeChecks) { | 2813 transformed.registerTypeUse(new TypeUse.instantiation( |
2787 onIsCheck(type, transformed); | 2814 backend.compiler.coreTypes.typeType)); |
2788 } | 2815 registerBackendImpact(transformed, impacts.typeLiteral); |
2789 } | |
2790 | |
2791 for (DartType type in worldImpact.onCatchTypes) { | |
2792 onIsCheck(type, transformed); | |
2793 } | 2816 } |
2794 | 2817 |
2795 for (MapLiteralUse mapLiteralUse in worldImpact.mapLiterals) { | 2818 for (MapLiteralUse mapLiteralUse in worldImpact.mapLiterals) { |
2796 // TODO(johnniwinther): Use the [isEmpty] property when factory | 2819 // TODO(johnniwinther): Use the [isEmpty] property when factory |
2797 // constructors are registered directly. | 2820 // constructors are registered directly. |
2798 if (mapLiteralUse.isConstant) { | 2821 if (mapLiteralUse.isConstant) { |
2799 registerBackendImpact(transformed, impacts.constantMapLiteral); | 2822 registerBackendImpact(transformed, impacts.constantMapLiteral); |
2800 } else { | 2823 } else { |
2801 transformed.registerInstantiatedType(mapLiteralUse.type); | 2824 transformed.registerTypeUse( |
| 2825 new TypeUse.instantiation(mapLiteralUse.type)); |
2802 } | 2826 } |
2803 registerRequiredType(mapLiteralUse.type); | 2827 registerRequiredType(mapLiteralUse.type); |
2804 } | 2828 } |
2805 | 2829 |
2806 for (ListLiteralUse listLiteralUse in worldImpact.listLiterals) { | 2830 for (ListLiteralUse listLiteralUse in worldImpact.listLiterals) { |
2807 // TODO(johnniwinther): Use the [isConstant] and [isEmpty] property when | 2831 // TODO(johnniwinther): Use the [isConstant] and [isEmpty] property when |
2808 // factory constructors are registered directly. | 2832 // factory constructors are registered directly. |
2809 transformed.registerInstantiatedType(listLiteralUse.type); | 2833 transformed.registerTypeUse( |
| 2834 new TypeUse.instantiation(listLiteralUse.type)); |
2810 registerRequiredType(listLiteralUse.type); | 2835 registerRequiredType(listLiteralUse.type); |
2811 } | 2836 } |
2812 | 2837 |
2813 if (worldImpact.typeLiterals.isNotEmpty) { | |
2814 transformed.registerInstantiatedType(backend.compiler.coreTypes.typeType); | |
2815 registerBackendImpact(transformed, impacts.typeLiteral); | |
2816 for (DartType typeLiteral in worldImpact.typeLiterals) { | |
2817 backend.customElementsAnalysis.registerTypeLiteral(typeLiteral); | |
2818 if (typeLiteral.isTypedef) { | |
2819 backend.compiler.world.allTypedefs.add(typeLiteral.element); | |
2820 } | |
2821 if (typeLiteral.isTypeVariable) { | |
2822 ClassElement cls = typeLiteral.element.enclosingClass; | |
2823 backend.rti.registerClassUsingTypeVariableExpression(cls); | |
2824 registerBackendImpact(transformed, impacts.typeVariableExpression); | |
2825 } | |
2826 } | |
2827 } | |
2828 | |
2829 if (worldImpact.constSymbolNames.isNotEmpty) { | 2838 if (worldImpact.constSymbolNames.isNotEmpty) { |
2830 registerBackendImpact(transformed, impacts.constSymbol); | 2839 registerBackendImpact(transformed, impacts.constSymbol); |
2831 for (String constSymbolName in worldImpact.constSymbolNames) { | 2840 for (String constSymbolName in worldImpact.constSymbolNames) { |
2832 backend.registerConstSymbol(constSymbolName); | 2841 backend.registerConstSymbol(constSymbolName); |
2833 } | 2842 } |
2834 } | 2843 } |
2835 | 2844 |
2836 if (worldImpact.closures.isNotEmpty) { | 2845 if (worldImpact.closures.isNotEmpty) { |
2837 registerBackendImpact(transformed, impacts.closure); | 2846 registerBackendImpact(transformed, impacts.closure); |
2838 for (LocalFunctionElement closure in worldImpact.closures) { | 2847 for (LocalFunctionElement closure in worldImpact.closures) { |
(...skipping 12 matching lines...) Expand all Loading... |
2851 BackendImpact backendImpact) { | 2860 BackendImpact backendImpact) { |
2852 for (Element staticUse in backendImpact.staticUses) { | 2861 for (Element staticUse in backendImpact.staticUses) { |
2853 assert(staticUse != null); | 2862 assert(staticUse != null); |
2854 backend.registerBackendUse(staticUse); | 2863 backend.registerBackendUse(staticUse); |
2855 worldImpact.registerStaticUse( | 2864 worldImpact.registerStaticUse( |
2856 // TODO(johnniwinther): Store the correct use in impacts. | 2865 // TODO(johnniwinther): Store the correct use in impacts. |
2857 new StaticUse.foreignUse(staticUse)); | 2866 new StaticUse.foreignUse(staticUse)); |
2858 } | 2867 } |
2859 for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) { | 2868 for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) { |
2860 backend.registerBackendUse(instantiatedType.element); | 2869 backend.registerBackendUse(instantiatedType.element); |
2861 worldImpact.registerInstantiatedType(instantiatedType); | 2870 worldImpact.registerTypeUse( |
| 2871 new TypeUse.instantiation(instantiatedType)); |
2862 } | 2872 } |
2863 for (ClassElement cls in backendImpact.instantiatedClasses) { | 2873 for (ClassElement cls in backendImpact.instantiatedClasses) { |
2864 cls.ensureResolved(backend.resolution); | 2874 cls.ensureResolved(backend.resolution); |
2865 backend.registerBackendUse(cls); | 2875 backend.registerBackendUse(cls); |
2866 worldImpact.registerInstantiatedType(cls.rawType); | 2876 worldImpact.registerTypeUse( |
| 2877 new TypeUse.instantiation(cls.rawType)); |
2867 } | 2878 } |
2868 for (BackendImpact otherImpact in backendImpact.otherImpacts) { | 2879 for (BackendImpact otherImpact in backendImpact.otherImpacts) { |
2869 registerBackendImpact(worldImpact, otherImpact); | 2880 registerBackendImpact(worldImpact, otherImpact); |
2870 } | 2881 } |
2871 } | 2882 } |
2872 | 2883 |
2873 /// Register [type] as required for the runtime type information system. | 2884 /// Register [type] as required for the runtime type information system. |
2874 void registerRequiredType(DartType type) { | 2885 void registerRequiredType(DartType type) { |
2875 // If [argument] has type variables or is a type variable, this method | 2886 // If [argument] has type variables or is a type variable, this method |
2876 // registers a RTI dependency between the class where the type variable is | 2887 // registers a RTI dependency between the class where the type variable is |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2955 registerBackendImpact(transformed, impacts.nativeTypeCheck); | 2966 registerBackendImpact(transformed, impacts.nativeTypeCheck); |
2956 } | 2967 } |
2957 } | 2968 } |
2958 | 2969 |
2959 @override | 2970 @override |
2960 WorldImpact transformCodegenImpact(CodegenImpact impact) { | 2971 WorldImpact transformCodegenImpact(CodegenImpact impact) { |
2961 TransformedWorldImpact transformed = new TransformedWorldImpact(impact); | 2972 TransformedWorldImpact transformed = new TransformedWorldImpact(impact); |
2962 EagerRegistry registry = impact.registry; | 2973 EagerRegistry registry = impact.registry; |
2963 Enqueuer world = registry.world; | 2974 Enqueuer world = registry.world; |
2964 | 2975 |
2965 for (InterfaceType type in impact.instantiatedTypes) { | 2976 for (TypeUse typeUse in impact.typeUses) { |
2966 backend.lookupMapAnalysis.registerInstantiatedType(type, registry); | 2977 DartType type = typeUse.type; |
2967 } | 2978 switch (typeUse.kind) { |
2968 | 2979 case TypeUseKind.INSTANTIATION: |
2969 for (DartType type in impact.isChecks) { | 2980 backend.lookupMapAnalysis.registerInstantiatedType(type, registry); |
2970 onIsCheckForCodegen(type, transformed); | 2981 break; |
| 2982 case TypeUseKind.IS_CHECK: |
| 2983 onIsCheckForCodegen(type, transformed); |
| 2984 break; |
| 2985 default: |
| 2986 } |
2971 } | 2987 } |
2972 | 2988 |
2973 for (ConstantValue constant in impact.compileTimeConstants) { | 2989 for (ConstantValue constant in impact.compileTimeConstants) { |
2974 backend.registerCompileTimeConstant(constant, registry); | 2990 backend.registerCompileTimeConstant(constant, registry); |
2975 backend.addCompileTimeConstantForEmission(constant); | 2991 backend.addCompileTimeConstantForEmission(constant); |
2976 } | 2992 } |
2977 | 2993 |
2978 for (Pair<DartType, DartType> check in | 2994 for (Pair<DartType, DartType> check in |
2979 impact.typeVariableBoundsSubtypeChecks) { | 2995 impact.typeVariableBoundsSubtypeChecks) { |
2980 backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b); | 2996 backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3022 } | 3038 } |
3023 } | 3039 } |
3024 | 3040 |
3025 /// Records that [constant] is used by the element behind [registry]. | 3041 /// Records that [constant] is used by the element behind [registry]. |
3026 class Dependency { | 3042 class Dependency { |
3027 final ConstantValue constant; | 3043 final ConstantValue constant; |
3028 final Element annotatedElement; | 3044 final Element annotatedElement; |
3029 | 3045 |
3030 const Dependency(this.constant, this.annotatedElement); | 3046 const Dependency(this.constant, this.annotatedElement); |
3031 } | 3047 } |
OLD | NEW |