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

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

Issue 12525007: Record dependency information to implement first version of dependency (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 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
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 834 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 void addInterceptors(ClassElement cls, Enqueuer enqueuer) { 845 void addInterceptors(ClassElement cls, Enqueuer enqueuer) {
846 if (enqueuer.isResolutionQueue) { 846 if (enqueuer.isResolutionQueue) {
847 cls.ensureResolved(compiler); 847 cls.ensureResolved(compiler);
848 cls.forEachMember((ClassElement classElement, Element member) { 848 cls.forEachMember((ClassElement classElement, Element member) {
849 Set<Element> set = interceptedElements.putIfAbsent( 849 Set<Element> set = interceptedElements.putIfAbsent(
850 member.name, () => new Set<Element>()); 850 member.name, () => new Set<Element>());
851 set.add(member); 851 set.add(member);
852 }, 852 },
853 includeSuperMembers: true); 853 includeSuperMembers: true);
854 } 854 }
855 enqueuer.registerInstantiatedClass(cls); 855 enqueuer.registerInstantiatedClass(cls, compiler.globalDependencies);
856 } 856 }
857 857
858 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { 858 void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
859 String name = namer.getInterceptorName(getInterceptorMethod, classes); 859 String name = namer.getInterceptorName(getInterceptorMethod, classes);
860 if (classes.contains(compiler.objectClass)) { 860 if (classes.contains(compiler.objectClass)) {
861 // We can't use a specialized [getInterceptorMethod], so we make 861 // We can't use a specialized [getInterceptorMethod], so we make
862 // sure we emit the one with all checks. 862 // sure we emit the one with all checks.
863 specializedGetInterceptors[name] = interceptedClasses; 863 specializedGetInterceptors[name] = interceptedClasses;
864 } else { 864 } else {
865 specializedGetInterceptors[name] = classes; 865 specializedGetInterceptors[name] = classes;
866 } 866 }
867 } 867 }
868 868
869 void initializeNoSuchMethod() { 869 void initializeNoSuchMethod() {
870 // In case the emitter generates noSuchMethod calls, we need to 870 // In case the emitter generates noSuchMethod calls, we need to
871 // make sure all [noSuchMethod] methods know they might take a 871 // make sure all [noSuchMethod] methods know they might take a
872 // [JsInvocationMirror] as parameter. 872 // [JsInvocationMirror] as parameter.
873 HTypeList types = new HTypeList(1); 873 HTypeList types = new HTypeList(1);
874 types[0] = new HType.nonNullExact( 874 types[0] = new HType.nonNullExact(
875 compiler.jsInvocationMirrorClass.computeType(compiler), 875 compiler.jsInvocationMirrorClass.computeType(compiler),
876 compiler); 876 compiler);
877 argumentTypes.registerDynamicInvocation(types, new Selector.noSuchMethod()); 877 argumentTypes.registerDynamicInvocation(types, new Selector.noSuchMethod());
878 } 878 }
879 879
880 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) { 880 void registerInstantiatedClass(ClassElement cls,
881 Enqueuer enqueuer,
882 TreeElements elements) {
881 if (!seenAnyClass) { 883 if (!seenAnyClass) {
882 initializeNoSuchMethod(); 884 initializeNoSuchMethod();
883 seenAnyClass = true; 885 seenAnyClass = true;
884 } 886 }
885 887
886 // Register any helper that will be needed by the backend. 888 // Register any helper that will be needed by the backend.
887 if (enqueuer.isResolutionQueue) { 889 if (enqueuer.isResolutionQueue) {
888 if (cls == compiler.intClass 890 if (cls == compiler.intClass
889 || cls == compiler.doubleClass 891 || cls == compiler.doubleClass
890 || cls == compiler.numClass) { 892 || cls == compiler.numClass) {
891 // The backend will try to optimize number operations and use the 893 // The backend will try to optimize number operations and use the
892 // `iae` helper directly. 894 // `iae` helper directly.
893 enqueuer.registerStaticUse( 895 enqueuer.registerStaticUse(
894 compiler.findHelper(const SourceString('iae'))); 896 compiler.findHelper(const SourceString('iae')));
895 } else if (cls == compiler.listClass 897 } else if (cls == compiler.listClass
896 || cls == compiler.stringClass) { 898 || cls == compiler.stringClass) {
897 // The backend will try to optimize array and string access and use the 899 // The backend will try to optimize array and string access and use the
898 // `ioore` and `iae` helpers directly. 900 // `ioore` and `iae` helpers directly.
899 enqueuer.registerStaticUse( 901 enqueuer.registerStaticUse(
900 compiler.findHelper(const SourceString('ioore'))); 902 compiler.findHelper(const SourceString('ioore')));
901 enqueuer.registerStaticUse( 903 enqueuer.registerStaticUse(
902 compiler.findHelper(const SourceString('iae'))); 904 compiler.findHelper(const SourceString('iae')));
903 } else if (cls == compiler.functionClass) { 905 } else if (cls == compiler.functionClass) {
904 enqueuer.registerInstantiatedClass(compiler.closureClass); 906 enqueuer.registerInstantiatedClass(compiler.closureClass, elements);
905 } else if (cls == compiler.mapClass) { 907 } else if (cls == compiler.mapClass) {
906 // The backend will use a literal list to initialize the entries 908 // The backend will use a literal list to initialize the entries
907 // of the map. 909 // of the map.
908 enqueuer.registerInstantiatedClass(compiler.listClass); 910 enqueuer.registerInstantiatedClass(compiler.listClass, elements);
909 enqueuer.registerInstantiatedClass(compiler.mapLiteralClass); 911 enqueuer.registerInstantiatedClass(compiler.mapLiteralClass, elements);
910 enqueueInResolution(getMapMaker()); 912 enqueueInResolution(getMapMaker(), elements);
911 } 913 }
912 } 914 }
913 ClassElement result = null; 915 ClassElement result = null;
914 if (cls == compiler.stringClass) { 916 if (cls == compiler.stringClass) {
915 addInterceptors(jsStringClass, enqueuer); 917 addInterceptors(jsStringClass, enqueuer);
916 } else if (cls == compiler.listClass) { 918 } else if (cls == compiler.listClass) {
917 addInterceptors(jsArrayClass, enqueuer); 919 addInterceptors(jsArrayClass, enqueuer);
918 } else if (cls == compiler.intClass) { 920 } else if (cls == compiler.intClass) {
919 addInterceptors(jsIntClass, enqueuer); 921 addInterceptors(jsIntClass, enqueuer);
920 addInterceptors(jsNumberClass, enqueuer); 922 addInterceptors(jsNumberClass, enqueuer);
(...skipping 11 matching lines...) Expand all
932 addInterceptors(jsDoubleClass, enqueuer); 934 addInterceptors(jsDoubleClass, enqueuer);
933 addInterceptors(jsNumberClass, enqueuer); 935 addInterceptors(jsNumberClass, enqueuer);
934 } else if (cls == compiler.mapClass) { 936 } else if (cls == compiler.mapClass) {
935 } 937 }
936 938
937 if (compiler.enableTypeAssertions) { 939 if (compiler.enableTypeAssertions) {
938 // We need to register is checks for assignments to fields. 940 // We need to register is checks for assignments to fields.
939 cls.forEachLocalMember((Element member) { 941 cls.forEachLocalMember((Element member) {
940 if (!member.isInstanceMember() || !member.isField()) return; 942 if (!member.isInstanceMember() || !member.isField()) return;
941 DartType type = member.computeType(compiler); 943 DartType type = member.computeType(compiler);
942 enqueuer.registerIsCheck(type); 944 enqueuer.registerIsCheck(type, compiler.globalDependencies);
943 }); 945 });
944 } 946 }
945 } 947 }
946 948
947 JavaScriptItemCompilationContext createItemCompilationContext() { 949 JavaScriptItemCompilationContext createItemCompilationContext() {
948 return new JavaScriptItemCompilationContext(); 950 return new JavaScriptItemCompilationContext();
949 } 951 }
950 952
951 void addBackendRtiDependencies(World world) { 953 void addBackendRtiDependencies(World world) {
952 if (jsArrayClass != null) { 954 if (jsArrayClass != null) {
953 world.registerRtiDependency(jsArrayClass, compiler.listClass); 955 world.registerRtiDependency(jsArrayClass, compiler.listClass);
954 } 956 }
955 } 957 }
956 958
957 void enqueueHelpers(ResolutionEnqueuer world) { 959 void enqueueHelpers(ResolutionEnqueuer world) {
958 jsIndexingBehaviorInterface = 960 jsIndexingBehaviorInterface =
959 compiler.findHelper(const SourceString('JavaScriptIndexingBehavior')); 961 compiler.findHelper(const SourceString('JavaScriptIndexingBehavior'));
960 if (jsIndexingBehaviorInterface != null) { 962 if (jsIndexingBehaviorInterface != null) {
961 world.registerIsCheck(jsIndexingBehaviorInterface.computeType(compiler)); 963 world.registerIsCheck(jsIndexingBehaviorInterface.computeType(compiler),
964 compiler.globalDependencies);
962 } 965 }
963 966
964 if (compiler.enableTypeAssertions) { 967 if (compiler.enableTypeAssertions) {
965 // Unconditionally register the helper that checks if the 968 // Unconditionally register the helper that checks if the
966 // expression in an if/while/for is a boolean. 969 // expression in an if/while/for is a boolean.
967 // TODO(ngeoffray): Should we have the resolver register those instead? 970 // TODO(ngeoffray): Should we have the resolver register those instead?
968 Element e = 971 Element e =
969 compiler.findHelper(const SourceString('boolConversionCheck')); 972 compiler.findHelper(const SourceString('boolConversionCheck'));
970 if (e != null) world.addToWorkList(e); 973 if (e != null) world.addToWorkList(e);
971 } 974 }
972 } 975 }
973 976
974 void registerStringInterpolation() { 977 void registerStringInterpolation(TreeElements elements) {
975 enqueueInResolution(getStringInterpolationHelper()); 978 enqueueInResolution(getStringInterpolationHelper(), elements);
976 } 979 }
977 980
978 void registerCatchStatement() { 981 void registerCatchStatement(TreeElements elements) {
979 enqueueInResolution(getExceptionUnwrapper()); 982 enqueueInResolution(getExceptionUnwrapper(), elements);
980 } 983 }
981 984
982 void registerThrow() { 985 void registerThrow(TreeElements elements) {
983 enqueueInResolution(getThrowHelper()); 986 enqueueInResolution(getThrowHelper(), elements);
984 } 987 }
985 988
986 void registerLazyField() { 989 void registerLazyField(TreeElements elements) {
987 enqueueInResolution(getCyclicThrowHelper()); 990 enqueueInResolution(getCyclicThrowHelper(), elements);
988 } 991 }
989 992
990 void registerTypeLiteral() { 993 void registerTypeLiteral(TreeElements elements) {
991 enqueueInResolution(getCreateRuntimeType()); 994 enqueueInResolution(getCreateRuntimeType(), elements);
992 } 995 }
993 996
994 void registerStackTraceInCatch() { 997 void registerStackTraceInCatch(TreeElements elements) {
995 enqueueInResolution(getTraceFromException()); 998 enqueueInResolution(getTraceFromException(), elements);
996 } 999 }
997 1000
998 void registerSetRuntimeType() { 1001 void registerSetRuntimeType(TreeElements elements) {
999 enqueueInResolution(getSetRuntimeTypeInfo()); 1002 enqueueInResolution(getSetRuntimeTypeInfo(), elements);
1000 } 1003 }
1001 1004
1002 void registerGetRuntimeTypeArgument() { 1005 void registerGetRuntimeTypeArgument(TreeElements elements) {
1003 enqueueInResolution(getGetRuntimeTypeArgument()); 1006 enqueueInResolution(getGetRuntimeTypeArgument(), elements);
1004 } 1007 }
1005 1008
1006 void registerRuntimeType() { 1009 void registerRuntimeType(TreeElements elements) {
1007 enqueueInResolution(getSetRuntimeTypeInfo()); 1010 enqueueInResolution(getSetRuntimeTypeInfo(), elements);
1008 enqueueInResolution(getGetRuntimeTypeInfo()); 1011 enqueueInResolution(getGetRuntimeTypeInfo(), elements);
1009 enqueueInResolution(getGetRuntimeTypeArgument()); 1012 enqueueInResolution(getGetRuntimeTypeArgument(), elements);
1010 compiler.enqueuer.resolution.registerInstantiatedClass(compiler.listClass); 1013 compiler.enqueuer.resolution.registerInstantiatedClass(
1014 compiler.listClass, elements);
1011 } 1015 }
1012 1016
1013 void registerIsCheck(DartType type, Enqueuer world) { 1017 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) {
1014 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; 1018 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE;
1015 if (!type.isRaw || isTypeVariable) { 1019 if (!type.isRaw || isTypeVariable) {
1016 enqueueInResolution(getSetRuntimeTypeInfo()); 1020 enqueueInResolution(getSetRuntimeTypeInfo(), elements);
1017 enqueueInResolution(getGetRuntimeTypeInfo()); 1021 enqueueInResolution(getGetRuntimeTypeInfo(), elements);
1018 enqueueInResolution(getGetRuntimeTypeArgument()); 1022 enqueueInResolution(getGetRuntimeTypeArgument(), elements);
1019 enqueueInResolution(getCheckArguments()); 1023 enqueueInResolution(getCheckArguments(), elements);
1020 if (isTypeVariable) enqueueInResolution(getGetObjectIsSubtype()); 1024 if (isTypeVariable) {
1021 world.registerInstantiatedClass(compiler.listClass); 1025 enqueueInResolution(getGetObjectIsSubtype(), elements);
1026 }
1027 world.registerInstantiatedClass(compiler.listClass, elements);
1022 } 1028 }
1023 // [registerIsCheck] is also called for checked mode checks, so we 1029 // [registerIsCheck] is also called for checked mode checks, so we
1024 // need to register checked mode helpers. 1030 // need to register checked mode helpers.
1025 if (compiler.enableTypeAssertions) { 1031 if (compiler.enableTypeAssertions) {
1026 Element e = getCheckedModeHelper(type, typeCast: false); 1032 Element e = getCheckedModeHelper(type, typeCast: false);
1027 if (e != null) world.addToWorkList(e); 1033 if (e != null) world.addToWorkList(e);
1028 // We also need the native variant of the check (for DOM types). 1034 // We also need the native variant of the check (for DOM types).
1029 e = getNativeCheckedModeHelper(type, typeCast: false); 1035 e = getNativeCheckedModeHelper(type, typeCast: false);
1030 if (e != null) world.addToWorkList(e); 1036 if (e != null) world.addToWorkList(e);
1031 } 1037 }
1032 } 1038 }
1033 1039
1034 void registerAsCheck(DartType type) { 1040 void registerAsCheck(DartType type, TreeElements elements) {
1035 Element e = getCheckedModeHelper(type, typeCast: true); 1041 Element e = getCheckedModeHelper(type, typeCast: true);
1036 enqueueInResolution(e); 1042 enqueueInResolution(e, elements);
1037 // We also need the native variant of the check (for DOM types). 1043 // We also need the native variant of the check (for DOM types).
1038 e = getNativeCheckedModeHelper(type, typeCast: true); 1044 e = getNativeCheckedModeHelper(type, typeCast: true);
1039 enqueueInResolution(e); 1045 enqueueInResolution(e, elements);
1040 } 1046 }
1041 1047
1042 void registerThrowNoSuchMethod() { 1048 void registerThrowNoSuchMethod(TreeElements elements) {
1043 enqueueInResolution(getThrowNoSuchMethod()); 1049 enqueueInResolution(getThrowNoSuchMethod(), elements);
1044 } 1050 }
1045 1051
1046 void registerThrowRuntimeError() { 1052 void registerThrowRuntimeError(TreeElements elements) {
1047 enqueueInResolution(getThrowRuntimeError()); 1053 enqueueInResolution(getThrowRuntimeError(), elements);
1048 } 1054 }
1049 1055
1050 void registerAbstractClassInstantiation() { 1056 void registerAbstractClassInstantiation(TreeElements elements) {
1051 enqueueInResolution(getThrowAbstractClassInstantiationError()); 1057 enqueueInResolution(getThrowAbstractClassInstantiationError(), elements);
1052 } 1058 }
1053 1059
1054 void registerFallThroughError() { 1060 void registerFallThroughError(TreeElements elements) {
1055 enqueueInResolution(getFallThroughError()); 1061 enqueueInResolution(getFallThroughError(), elements);
1056 } 1062 }
1057 1063
1058 void registerSuperNoSuchMethod() { 1064 void registerSuperNoSuchMethod(TreeElements elements) {
1059 enqueueInResolution(getCreateInvocationMirror()); 1065 enqueueInResolution(getCreateInvocationMirror(), elements);
1060 enqueueInResolution( 1066 enqueueInResolution(
1061 compiler.objectClass.lookupLocalMember(Compiler.NO_SUCH_METHOD)); 1067 compiler.objectClass.lookupLocalMember(Compiler.NO_SUCH_METHOD),
1062 compiler.enqueuer.resolution.registerInstantiatedClass(compiler.listClass); 1068 elements);
1069 compiler.enqueuer.resolution.registerInstantiatedClass(
1070 compiler.listClass, elements);
1063 } 1071 }
1064 1072
1065 void enqueueInResolution(Element e) { 1073 void enqueueInResolution(Element e, TreeElements elements) {
1066 if (e != null) compiler.enqueuer.resolution.addToWorkList(e); 1074 if (e == null) return;
1075 ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution;
1076 enqueuer.addToWorkList(e);
1077 elements.registerBackendDependency(e);
1067 } 1078 }
1068 1079
1069 void registerConstantMap() { 1080 void registerConstantMap(TreeElements elements) {
1070 Element e = compiler.findHelper(const SourceString('ConstantMap')); 1081 Element e = compiler.findHelper(const SourceString('ConstantMap'));
1071 if (e != null) compiler.enqueuer.resolution.registerInstantiatedClass(e); 1082 if (e != null) {
1083 compiler.enqueuer.resolution.registerInstantiatedClass(e, elements);
1084 }
1072 e = compiler.findHelper(const SourceString('ConstantProtoMap')); 1085 e = compiler.findHelper(const SourceString('ConstantProtoMap'));
1073 if (e != null) compiler.enqueuer.resolution.registerInstantiatedClass(e); 1086 if (e != null) {
1087 compiler.enqueuer.resolution.registerInstantiatedClass(e, elements);
1088 }
1074 } 1089 }
1075 1090
1076 void codegen(CodegenWorkItem work) { 1091 void codegen(CodegenWorkItem work) {
1077 Element element = work.element; 1092 Element element = work.element;
1078 if (element.kind.category == ElementCategory.VARIABLE) { 1093 if (element.kind.category == ElementCategory.VARIABLE) {
1079 Constant initialValue = compiler.constantHandler.compileWorkItem(work); 1094 Constant initialValue = compiler.constantHandler.compileWorkItem(work);
1080 if (initialValue != null) { 1095 if (initialValue != null) {
1081 return; 1096 return;
1082 } else { 1097 } else {
1083 // If the constant-handler was not able to produce a result we have to 1098 // If the constant-handler was not able to produce a result we have to
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 * 1511 *
1497 * Invariant: [element] must be a declaration element. 1512 * Invariant: [element] must be a declaration element.
1498 */ 1513 */
1499 void eagerRecompile(Element element) { 1514 void eagerRecompile(Element element) {
1500 assert(invariant(element, element.isDeclaration)); 1515 assert(invariant(element, element.isDeclaration));
1501 generatedCode.remove(element); 1516 generatedCode.remove(element);
1502 generatedBailoutCode.remove(element); 1517 generatedBailoutCode.remove(element);
1503 compiler.enqueuer.codegen.addToWorkList(element); 1518 compiler.enqueuer.codegen.addToWorkList(element);
1504 } 1519 }
1505 } 1520 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698