| 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 |