Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 /** | 7 /** |
| 8 * Assigns JavaScript identifiers to Dart variables, class-names and members. | 8 * Assigns JavaScript identifiers to Dart variables, class-names and members. |
| 9 */ | 9 */ |
| 10 class Namer implements ClosureNamer { | 10 class Namer implements ClosureNamer { |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 249 final Set<String> usedGlobalNames; | 249 final Set<String> usedGlobalNames; |
| 250 final Set<String> usedInstanceNames; | 250 final Set<String> usedInstanceNames; |
| 251 final Map<String, String> globalNameMap; | 251 final Map<String, String> globalNameMap; |
| 252 final Map<String, String> suggestedGlobalNames; | 252 final Map<String, String> suggestedGlobalNames; |
| 253 final Map<String, String> instanceNameMap; | 253 final Map<String, String> instanceNameMap; |
| 254 final Map<String, String> suggestedInstanceNames; | 254 final Map<String, String> suggestedInstanceNames; |
| 255 | 255 |
| 256 final Map<String, String> operatorNameMap; | 256 final Map<String, String> operatorNameMap; |
| 257 final Map<String, int> popularNameCounters; | 257 final Map<String, int> popularNameCounters; |
| 258 | 258 |
| 259 final Map<Constant, String> constantNames; | 259 final Map<ConstantValue, String> constantNames; |
| 260 final Map<Constant, String> constantLongNames; | 260 final Map<ConstantValue, String> constantLongNames; |
| 261 ConstantCanonicalHasher constantHasher; | 261 ConstantCanonicalHasher constantHasher; |
| 262 | 262 |
| 263 // All alphanumeric characters. | 263 // All alphanumeric characters. |
| 264 static const String _alphaNumeric = | 264 static const String _alphaNumeric = |
| 265 'abcdefghijklmnopqrstuvwxyzABZDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; | 265 'abcdefghijklmnopqrstuvwxyzABZDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; |
| 266 | 266 |
| 267 Namer(Compiler compiler) | 267 Namer(Compiler compiler) |
| 268 : compiler = compiler, | 268 : compiler = compiler, |
| 269 globals = new Map<Element, String>(), | 269 globals = new Map<Element, String>(), |
| 270 shortPrivateNameOwners = new Map<String, LibraryElement>(), | 270 shortPrivateNameOwners = new Map<String, LibraryElement>(), |
| 271 usedGlobalNames = new Set<String>(), | 271 usedGlobalNames = new Set<String>(), |
| 272 usedInstanceNames = new Set<String>(), | 272 usedInstanceNames = new Set<String>(), |
| 273 instanceNameMap = new Map<String, String>(), | 273 instanceNameMap = new Map<String, String>(), |
| 274 operatorNameMap = new Map<String, String>(), | 274 operatorNameMap = new Map<String, String>(), |
| 275 globalNameMap = new Map<String, String>(), | 275 globalNameMap = new Map<String, String>(), |
| 276 suggestedGlobalNames = new Map<String, String>(), | 276 suggestedGlobalNames = new Map<String, String>(), |
| 277 suggestedInstanceNames = new Map<String, String>(), | 277 suggestedInstanceNames = new Map<String, String>(), |
| 278 popularNameCounters = new Map<String, int>(), | 278 popularNameCounters = new Map<String, int>(), |
| 279 constantNames = new Map<Constant, String>(), | 279 constantNames = new Map<ConstantValue, String>(), |
| 280 constantLongNames = new Map<Constant, String>(), | 280 constantLongNames = new Map<ConstantValue, String>(), |
| 281 constantHasher = new ConstantCanonicalHasher(compiler), | 281 constantHasher = new ConstantCanonicalHasher(compiler), |
| 282 functionTypeNamer = new FunctionTypeNamer(compiler); | 282 functionTypeNamer = new FunctionTypeNamer(compiler); |
| 283 | 283 |
| 284 JavaScriptBackend get backend => compiler.backend; | 284 JavaScriptBackend get backend => compiler.backend; |
| 285 | 285 |
| 286 String get isolateName => 'Isolate'; | 286 String get isolateName => 'Isolate'; |
| 287 String get isolatePropertiesName => r'$isolateProperties'; | 287 String get isolatePropertiesName => r'$isolateProperties'; |
| 288 /** | 288 /** |
| 289 * Some closures must contain their name. The name is stored in | 289 * Some closures must contain their name. The name is stored in |
| 290 * [STATIC_CLOSURE_NAME_NAME]. | 290 * [STATIC_CLOSURE_NAME_NAME]. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 302 case 'REFLECTABLE': return reflectableField; | 302 case 'REFLECTABLE': return reflectableField; |
| 303 case 'CLASS_DESCRIPTOR_PROPERTY': return classDescriptorProperty; | 303 case 'CLASS_DESCRIPTOR_PROPERTY': return classDescriptorProperty; |
| 304 default: | 304 default: |
| 305 compiler.reportError( | 305 compiler.reportError( |
| 306 node, MessageKind.GENERIC, | 306 node, MessageKind.GENERIC, |
| 307 {'text': 'Error: Namer has no name for "$name".'}); | 307 {'text': 'Error: Namer has no name for "$name".'}); |
| 308 return 'BROKEN'; | 308 return 'BROKEN'; |
| 309 } | 309 } |
| 310 } | 310 } |
| 311 | 311 |
| 312 String constantName(Constant constant) { | 312 String constantName(ConstantValue constant) { |
| 313 // In the current implementation it doesn't make sense to give names to | 313 // In the current implementation it doesn't make sense to give names to |
| 314 // function constants since the function-implementation itself serves as | 314 // function constants since the function-implementation itself serves as |
| 315 // constant and can be accessed directly. | 315 // constant and can be accessed directly. |
| 316 assert(!constant.isFunction); | 316 assert(!constant.isFunction); |
| 317 String result = constantNames[constant]; | 317 String result = constantNames[constant]; |
| 318 if (result == null) { | 318 if (result == null) { |
| 319 String longName = constantLongName(constant); | 319 String longName = constantLongName(constant); |
| 320 result = getFreshName(longName, usedGlobalNames, suggestedGlobalNames, | 320 result = getFreshName(longName, usedGlobalNames, suggestedGlobalNames, |
| 321 ensureSafe: true); | 321 ensureSafe: true); |
| 322 constantNames[constant] = result; | 322 constantNames[constant] = result; |
| 323 } | 323 } |
| 324 return result; | 324 return result; |
| 325 } | 325 } |
| 326 | 326 |
| 327 // The long name is unminified and may have collisions. | 327 // The long name is unminified and may have collisions. |
| 328 String constantLongName(Constant constant) { | 328 String constantLongName(ConstantValue constant) { |
| 329 String longName = constantLongNames[constant]; | 329 String longName = constantLongNames[constant]; |
| 330 if (longName == null) { | 330 if (longName == null) { |
| 331 longName = new ConstantNamingVisitor(compiler, constantHasher) | 331 longName = new ConstantNamingVisitor(compiler, constantHasher) |
| 332 .getName(constant); | 332 .getName(constant); |
| 333 constantLongNames[constant] = longName; | 333 constantLongNames[constant] = longName; |
| 334 } | 334 } |
| 335 return longName; | 335 return longName; |
| 336 } | 336 } |
| 337 | 337 |
| 338 String breakLabelName(LabelDefinition label) { | 338 String breakLabelName(LabelDefinition label) { |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 873 [globalObjectFor(element), getStaticClosureName(element)]); | 873 [globalObjectFor(element), getStaticClosureName(element)]); |
| 874 } | 874 } |
| 875 | 875 |
| 876 // This name is used as part of the name of a TypeConstant | 876 // This name is used as part of the name of a TypeConstant |
| 877 String uniqueNameForTypeConstantElement(Element element) { | 877 String uniqueNameForTypeConstantElement(Element element) { |
| 878 // TODO(sra): If we replace the period with an identifier character, | 878 // TODO(sra): If we replace the period with an identifier character, |
| 879 // TypeConstants will have better names in unminified code. | 879 // TypeConstants will have better names in unminified code. |
| 880 return "${globalObjectFor(element)}.${getNameX(element)}"; | 880 return "${globalObjectFor(element)}.${getNameX(element)}"; |
| 881 } | 881 } |
| 882 | 882 |
| 883 String globalObjectForConstant(Constant constant) => 'C'; | 883 String globalObjectForConstant(ConstantValue constant) => 'C'; |
| 884 | 884 |
| 885 String operatorIsPrefix() => r'$is'; | 885 String operatorIsPrefix() => r'$is'; |
| 886 | 886 |
| 887 String operatorAsPrefix() => r'$as'; | 887 String operatorAsPrefix() => r'$as'; |
| 888 | 888 |
| 889 String operatorSignature() => r'$signature'; | 889 String operatorSignature() => r'$signature'; |
| 890 | 890 |
| 891 String typedefTag() => r'typedef'; | 891 String typedefTag() => r'typedef'; |
| 892 | 892 |
| 893 String functionTypeTag() => r'func'; | 893 String functionTypeTag() => r'func'; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 999 | 999 |
| 1000 void forgetElement(Element element) { | 1000 void forgetElement(Element element) { |
| 1001 String globalName = globals[element]; | 1001 String globalName = globals[element]; |
| 1002 invariant(element, globalName != null, message: 'No global name.'); | 1002 invariant(element, globalName != null, message: 'No global name.'); |
| 1003 usedGlobalNames.remove(globalName); | 1003 usedGlobalNames.remove(globalName); |
| 1004 globals.remove(element); | 1004 globals.remove(element); |
| 1005 } | 1005 } |
| 1006 } | 1006 } |
| 1007 | 1007 |
| 1008 /** | 1008 /** |
| 1009 * Generator of names for [Constant] values. | 1009 * Generator of names for [ConstantValue] values. |
| 1010 * | 1010 * |
| 1011 * The names are stable under perturbations of the source. The name is either a | 1011 * The names are stable under perturbations of the source. The name is either a |
| 1012 * short sequence of words, if this can be found from the constant, or a type | 1012 * short sequence of words, if this can be found from the constant, or a type |
| 1013 * followed by a hash tag. | 1013 * followed by a hash tag. |
| 1014 * | 1014 * |
| 1015 * List_imX // A List, with hash tag. | 1015 * List_imX // A List, with hash tag. |
| 1016 * C_Sentinel // const Sentinel(), "C_" added to avoid clash | 1016 * C_Sentinel // const Sentinel(), "C_" added to avoid clash |
| 1017 * // with class name. | 1017 * // with class name. |
| 1018 * JSInt_methods // an interceptor. | 1018 * JSInt_methods // an interceptor. |
| 1019 * Duration_16000 // const Duration(milliseconds: 16) | 1019 * Duration_16000 // const Duration(milliseconds: 16) |
| 1020 * EventKeyProvider_keyup // const EventKeyProvider('keyup') | 1020 * EventKeyProvider_keyup // const EventKeyProvider('keyup') |
| 1021 * | 1021 * |
| 1022 */ | 1022 */ |
| 1023 class ConstantNamingVisitor implements ConstantVisitor { | 1023 class ConstantNamingVisitor implements ConstantValueVisitor { |
| 1024 | 1024 |
| 1025 static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$'); | 1025 static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$'); |
| 1026 static const MAX_FRAGMENTS = 5; | 1026 static const MAX_FRAGMENTS = 5; |
| 1027 static const MAX_EXTRA_LENGTH = 30; | 1027 static const MAX_EXTRA_LENGTH = 30; |
| 1028 static const DEFAULT_TAG_LENGTH = 3; | 1028 static const DEFAULT_TAG_LENGTH = 3; |
| 1029 | 1029 |
| 1030 final Compiler compiler; | 1030 final Compiler compiler; |
| 1031 final ConstantCanonicalHasher hasher; | 1031 final ConstantCanonicalHasher hasher; |
| 1032 | 1032 |
| 1033 String root = null; // First word, usually a type name. | 1033 String root = null; // First word, usually a type name. |
| 1034 bool failed = false; // Failed to generate something pretty. | 1034 bool failed = false; // Failed to generate something pretty. |
| 1035 List<String> fragments = <String>[]; | 1035 List<String> fragments = <String>[]; |
| 1036 int length = 0; | 1036 int length = 0; |
| 1037 | 1037 |
| 1038 ConstantNamingVisitor(this.compiler, this.hasher); | 1038 ConstantNamingVisitor(this.compiler, this.hasher); |
| 1039 | 1039 |
| 1040 String getName(Constant constant) { | 1040 String getName(ConstantValue constant) { |
| 1041 _visit(constant); | 1041 _visit(constant); |
| 1042 if (root == null) return 'CONSTANT'; | 1042 if (root == null) return 'CONSTANT'; |
| 1043 if (failed) return '${root}_${getHashTag(constant, DEFAULT_TAG_LENGTH)}'; | 1043 if (failed) return '${root}_${getHashTag(constant, DEFAULT_TAG_LENGTH)}'; |
| 1044 if (fragments.length == 1) return 'C_${root}'; | 1044 if (fragments.length == 1) return 'C_${root}'; |
| 1045 return fragments.join('_'); | 1045 return fragments.join('_'); |
| 1046 } | 1046 } |
| 1047 | 1047 |
| 1048 String getHashTag(Constant constant, int width) => | 1048 String getHashTag(ConstantValue constant, int width) => |
| 1049 hashWord(hasher.getHash(constant), width); | 1049 hashWord(hasher.getHash(constant), width); |
| 1050 | 1050 |
| 1051 String hashWord(int hash, int length) { | 1051 String hashWord(int hash, int length) { |
| 1052 hash &= 0x1fffffff; | 1052 hash &= 0x1fffffff; |
| 1053 StringBuffer sb = new StringBuffer(); | 1053 StringBuffer sb = new StringBuffer(); |
| 1054 for (int i = 0; i < length; i++) { | 1054 for (int i = 0; i < length; i++) { |
| 1055 int digit = hash % 62; | 1055 int digit = hash % 62; |
| 1056 sb.write('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' | 1056 sb.write('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' |
| 1057 [digit]); | 1057 [digit]); |
| 1058 hash ~/= 62; | 1058 hash ~/= 62; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1079 } | 1079 } |
| 1080 | 1080 |
| 1081 void addIdentifier(String fragment) { | 1081 void addIdentifier(String fragment) { |
| 1082 if (fragment.length <= MAX_EXTRA_LENGTH && IDENTIFIER.hasMatch(fragment)) { | 1082 if (fragment.length <= MAX_EXTRA_LENGTH && IDENTIFIER.hasMatch(fragment)) { |
| 1083 add(fragment); | 1083 add(fragment); |
| 1084 } else { | 1084 } else { |
| 1085 failed = true; | 1085 failed = true; |
| 1086 } | 1086 } |
| 1087 } | 1087 } |
| 1088 | 1088 |
| 1089 _visit(Constant constant) { | 1089 _visit(ConstantValue constant) { |
| 1090 return constant.accept(this); | 1090 return constant.accept(this); |
| 1091 } | 1091 } |
| 1092 | 1092 |
| 1093 visitFunction(FunctionConstant constant) { | 1093 visitFunction(FunctionConstantValue constant) { |
| 1094 add(constant.element.name); | 1094 add(constant.element.name); |
| 1095 } | 1095 } |
| 1096 | 1096 |
| 1097 visitNull(NullConstant constant) { | 1097 visitNull(NullConstantValue constant) { |
| 1098 add('null'); | 1098 add('null'); |
| 1099 } | 1099 } |
| 1100 | 1100 |
| 1101 visitInt(IntConstant constant) { | 1101 visitInt(IntConstantValue constant) { |
| 1102 // No `addRoot` since IntConstants are always inlined. | 1102 // No `addRoot` since IntConstants are always inlined. |
| 1103 if (constant.value < 0) { | 1103 if (constant.primitiveValue < 0) { |
| 1104 add('m${-constant.value}'); | 1104 add('m${-constant.primitiveValue}'); |
| 1105 } else { | 1105 } else { |
| 1106 add('${constant.value}'); | 1106 add('${constant.primitiveValue}'); |
| 1107 } | 1107 } |
| 1108 } | 1108 } |
| 1109 | 1109 |
| 1110 visitDouble(DoubleConstant constant) { | 1110 visitDouble(DoubleConstantValue constant) { |
| 1111 failed = true; | 1111 failed = true; |
| 1112 } | 1112 } |
| 1113 | 1113 |
| 1114 visitTrue(TrueConstant constant) { | 1114 visitTrue(TrueConstantValue constant) { |
| 1115 add('true'); | 1115 add('true'); |
| 1116 } | 1116 } |
| 1117 | 1117 |
| 1118 visitFalse(FalseConstant constant) { | 1118 visitFalse(FalseConstantValue constant) { |
| 1119 add('false'); | 1119 add('false'); |
| 1120 } | 1120 } |
| 1121 | 1121 |
| 1122 visitString(StringConstant constant) { | 1122 visitString(StringConstantValue constant) { |
| 1123 // No `addRoot` since string constants are always inlined. | 1123 // No `addRoot` since string constants are always inlined. |
| 1124 addIdentifier(constant.value.slowToString()); | 1124 addIdentifier(constant.primitiveValue.slowToString()); |
| 1125 } | 1125 } |
| 1126 | 1126 |
| 1127 visitList(ListConstant constant) { | 1127 visitList(ListConstantValue constant) { |
| 1128 // TODO(9476): Incorporate type parameters into name. | 1128 // TODO(9476): Incorporate type parameters into name. |
| 1129 addRoot('List'); | 1129 addRoot('List'); |
| 1130 int length = constant.length; | 1130 int length = constant.length; |
| 1131 if (constant.length == 0) { | 1131 if (constant.length == 0) { |
| 1132 add('empty'); | 1132 add('empty'); |
| 1133 } else if (length >= MAX_FRAGMENTS) { | 1133 } else if (length >= MAX_FRAGMENTS) { |
| 1134 failed = true; | 1134 failed = true; |
| 1135 } else { | 1135 } else { |
| 1136 for (int i = 0; i < length; i++) { | 1136 for (int i = 0; i < length; i++) { |
| 1137 _visit(constant.entries[i]); | 1137 _visit(constant.entries[i]); |
| 1138 if (failed) break; | 1138 if (failed) break; |
| 1139 } | 1139 } |
| 1140 } | 1140 } |
| 1141 } | 1141 } |
| 1142 | 1142 |
| 1143 visitMap(JavaScriptMapConstant constant) { | 1143 visitMap(JavaScriptMapConstant constant) { |
| 1144 // TODO(9476): Incorporate type parameters into name. | 1144 // TODO(9476): Incorporate type parameters into name. |
| 1145 addRoot('Map'); | 1145 addRoot('Map'); |
| 1146 if (constant.length == 0) { | 1146 if (constant.length == 0) { |
| 1147 add('empty'); | 1147 add('empty'); |
| 1148 } else { | 1148 } else { |
| 1149 // Using some bits from the keys hash tag groups the names Maps with the | 1149 // Using some bits from the keys hash tag groups the names Maps with the |
| 1150 // same structure. | 1150 // same structure. |
| 1151 add(getHashTag(constant.keyList, 2) + getHashTag(constant, 3)); | 1151 add(getHashTag(constant.keyList, 2) + getHashTag(constant, 3)); |
| 1152 } | 1152 } |
| 1153 } | 1153 } |
| 1154 | 1154 |
| 1155 visitConstructed(ConstructedConstant constant) { | 1155 visitConstructed(ConstructedConstantValue constant) { |
| 1156 addRoot(constant.type.element.name); | 1156 addRoot(constant.type.element.name); |
| 1157 for (int i = 0; i < constant.fields.length; i++) { | 1157 for (int i = 0; i < constant.fields.length; i++) { |
| 1158 _visit(constant.fields[i]); | 1158 _visit(constant.fields[i]); |
| 1159 if (failed) return; | 1159 if (failed) return; |
| 1160 } | 1160 } |
| 1161 } | 1161 } |
| 1162 | 1162 |
| 1163 visitType(TypeConstant constant) { | 1163 visitType(TypeConstantValue constant) { |
| 1164 addRoot('Type'); | 1164 addRoot('Type'); |
| 1165 DartType type = constant.representedType; | 1165 DartType type = constant.representedType; |
| 1166 JavaScriptBackend backend = compiler.backend; | 1166 JavaScriptBackend backend = compiler.backend; |
| 1167 String name = backend.rti.getTypeRepresentationForTypeConstant(type); | 1167 String name = backend.rti.getTypeRepresentationForTypeConstant(type); |
| 1168 addIdentifier(name); | 1168 addIdentifier(name); |
| 1169 } | 1169 } |
| 1170 | 1170 |
| 1171 visitInterceptor(InterceptorConstant constant) { | 1171 visitInterceptor(InterceptorConstantValue constant) { |
| 1172 addRoot(constant.dispatchedType.element.name); | 1172 addRoot(constant.dispatchedType.element.name); |
| 1173 add('methods'); | 1173 add('methods'); |
| 1174 } | 1174 } |
| 1175 | 1175 |
| 1176 visitDummy(DummyConstant constant) { | 1176 visitDummy(DummyConstantValue constant) { |
| 1177 add('dummy_receiver'); | 1177 add('dummy_receiver'); |
| 1178 } | 1178 } |
| 1179 | 1179 |
| 1180 visitDeferred(DeferredConstant constant) { | 1180 visitDeferred(DeferredConstantValue constant) { |
| 1181 addRoot('Deferred'); | 1181 addRoot('Deferred'); |
| 1182 } | 1182 } |
| 1183 } | 1183 } |
| 1184 | 1184 |
| 1185 /** | 1185 /** |
| 1186 * Generates canonical hash values for [Constant]s. | 1186 * Generates canonical hash values for [ConstantValue]s. |
| 1187 * | 1187 * |
| 1188 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, | 1188 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, |
| 1189 * so it can't be used for generating names. This hasher keeps consistency | 1189 * so it can't be used for generating names. This hasher keeps consistency |
| 1190 * between runs by basing hash values of the names of elements, rather than | 1190 * between runs by basing hash values of the names of elements, rather than |
| 1191 * their hashCodes. | 1191 * their hashCodes. |
| 1192 */ | 1192 */ |
| 1193 class ConstantCanonicalHasher implements ConstantVisitor<int> { | 1193 class ConstantCanonicalHasher implements ConstantValueVisitor<int> { |
| 1194 | 1194 |
| 1195 static const _MASK = 0x1fffffff; | 1195 static const _MASK = 0x1fffffff; |
| 1196 static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024; | 1196 static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024; |
| 1197 | 1197 |
| 1198 | 1198 |
| 1199 final Compiler compiler; | 1199 final Compiler compiler; |
| 1200 final Map<Constant, int> hashes = new Map<Constant, int>(); | 1200 final Map<ConstantValue, int> hashes = new Map<ConstantValue, int>(); |
| 1201 | 1201 |
| 1202 ConstantCanonicalHasher(this.compiler); | 1202 ConstantCanonicalHasher(this.compiler); |
| 1203 | 1203 |
| 1204 int getHash(Constant constant) => _visit(constant); | 1204 int getHash(ConstantValue constant) => _visit(constant); |
| 1205 | 1205 |
| 1206 int _visit(Constant constant) { | 1206 int _visit(ConstantValue constant) { |
| 1207 int hash = hashes[constant]; | 1207 int hash = hashes[constant]; |
| 1208 if (hash == null) { | 1208 if (hash == null) { |
| 1209 hash = _finish(constant.accept(this)); | 1209 hash = _finish(constant.accept(this)); |
| 1210 hashes[constant] = hash; | 1210 hashes[constant] = hash; |
| 1211 } | 1211 } |
| 1212 return hash; | 1212 return hash; |
| 1213 } | 1213 } |
| 1214 | 1214 |
| 1215 int visitNull(NullConstant constant) => 1; | 1215 int visitNull(NullConstantValue constant) => 1; |
| 1216 int visitTrue(TrueConstant constant) => 2; | 1216 int visitTrue(TrueConstantValue constant) => 2; |
| 1217 int visitFalse(FalseConstant constant) => 3; | 1217 int visitFalse(FalseConstantValue constant) => 3; |
| 1218 | 1218 |
| 1219 int visitFunction(FunctionConstant constant) { | 1219 int visitFunction(FunctionConstantValue constant) { |
| 1220 return _hashString(1, constant.element.name); | 1220 return _hashString(1, constant.element.name); |
| 1221 } | 1221 } |
| 1222 | 1222 |
| 1223 int visitInt(IntConstant constant) => _hashInt(constant.value); | 1223 int visitInt(IntConstantValue constant) => _hashInt(constant.primitiveValue); |
| 1224 | 1224 |
| 1225 int visitDouble(DoubleConstant constant) => _hashDouble(constant.value); | 1225 int visitDouble(DoubleConstantValue constant) => _hashDouble(constant.primitiv eValue); |
|
sigurdm
2014/10/01 07:46:47
Long line
Johnni Winther
2014/10/01 08:21:23
Done.
| |
| 1226 | 1226 |
| 1227 int visitString(StringConstant constant) { | 1227 int visitString(StringConstantValue constant) { |
| 1228 return _hashString(2, constant.value.slowToString()); | 1228 return _hashString(2, constant.primitiveValue.slowToString()); |
| 1229 } | 1229 } |
| 1230 | 1230 |
| 1231 int visitList(ListConstant constant) { | 1231 int visitList(ListConstantValue constant) { |
| 1232 return _hashList(constant.length, constant.entries); | 1232 return _hashList(constant.length, constant.entries); |
| 1233 } | 1233 } |
| 1234 | 1234 |
| 1235 int visitMap(MapConstant constant) { | 1235 int visitMap(MapConstantValue constant) { |
| 1236 int hash = _hashList(constant.length, constant.keys); | 1236 int hash = _hashList(constant.length, constant.keys); |
| 1237 return _hashList(hash, constant.values); | 1237 return _hashList(hash, constant.values); |
| 1238 } | 1238 } |
| 1239 | 1239 |
| 1240 int visitConstructed(ConstructedConstant constant) { | 1240 int visitConstructed(ConstructedConstantValue constant) { |
| 1241 int hash = _hashString(3, constant.type.element.name); | 1241 int hash = _hashString(3, constant.type.element.name); |
| 1242 for (int i = 0; i < constant.fields.length; i++) { | 1242 for (int i = 0; i < constant.fields.length; i++) { |
| 1243 hash = _combine(hash, _visit(constant.fields[i])); | 1243 hash = _combine(hash, _visit(constant.fields[i])); |
| 1244 } | 1244 } |
| 1245 return hash; | 1245 return hash; |
| 1246 } | 1246 } |
| 1247 | 1247 |
| 1248 int visitType(TypeConstant constant) { | 1248 int visitType(TypeConstantValue constant) { |
| 1249 DartType type = constant.representedType; | 1249 DartType type = constant.representedType; |
| 1250 JavaScriptBackend backend = compiler.backend; | 1250 JavaScriptBackend backend = compiler.backend; |
| 1251 String name = backend.rti.getTypeRepresentationForTypeConstant(type); | 1251 String name = backend.rti.getTypeRepresentationForTypeConstant(type); |
| 1252 return _hashString(4, name); | 1252 return _hashString(4, name); |
| 1253 } | 1253 } |
| 1254 | 1254 |
| 1255 visitInterceptor(InterceptorConstant constant) { | 1255 visitInterceptor(InterceptorConstantValue constant) { |
| 1256 String typeName = constant.dispatchedType.element.name; | 1256 String typeName = constant.dispatchedType.element.name; |
| 1257 return _hashString(5, typeName); | 1257 return _hashString(5, typeName); |
| 1258 } | 1258 } |
| 1259 | 1259 |
| 1260 visitDummy(DummyConstant constant) { | 1260 visitDummy(DummyConstantValue constant) { |
| 1261 compiler.internalError(NO_LOCATION_SPANNABLE, | 1261 compiler.internalError(NO_LOCATION_SPANNABLE, |
| 1262 'DummyReceiverConstant should never be named and never be subconstant'); | 1262 'DummyReceiverConstant should never be named and never be subconstant'); |
| 1263 } | 1263 } |
| 1264 | 1264 |
| 1265 visitDeferred(DeferredConstant constant) { | 1265 visitDeferred(DeferredConstantValue constant) { |
| 1266 int hash = constant.prefix.hashCode; | 1266 int hash = constant.prefix.hashCode; |
| 1267 return _combine(hash, constant.referenced.accept(this)); | 1267 return _combine(hash, constant.referenced.accept(this)); |
| 1268 } | 1268 } |
| 1269 | 1269 |
| 1270 int _hashString(int hash, String s) { | 1270 int _hashString(int hash, String s) { |
| 1271 int length = s.length; | 1271 int length = s.length; |
| 1272 hash = _combine(hash, length); | 1272 hash = _combine(hash, length); |
| 1273 // Increasing stride is O(log N) on large strings which are unlikely to have | 1273 // Increasing stride is O(log N) on large strings which are unlikely to have |
| 1274 // many collisions. | 1274 // many collisions. |
| 1275 for (int i = 0; i < length; i += 1 + (i >> 2)) { | 1275 for (int i = 0; i < length; i += 1 + (i >> 2)) { |
| 1276 hash = _combine(hash, s.codeUnitAt(i)); | 1276 hash = _combine(hash, s.codeUnitAt(i)); |
| 1277 } | 1277 } |
| 1278 return hash; | 1278 return hash; |
| 1279 } | 1279 } |
| 1280 | 1280 |
| 1281 int _hashList(int hash, List<Constant> constants) { | 1281 int _hashList(int hash, List<ConstantValue> constants) { |
| 1282 for (Constant constant in constants) { | 1282 for (ConstantValue constant in constants) { |
| 1283 hash = _combine(hash, _visit(constant)); | 1283 hash = _combine(hash, _visit(constant)); |
| 1284 } | 1284 } |
| 1285 return hash; | 1285 return hash; |
| 1286 } | 1286 } |
| 1287 | 1287 |
| 1288 static int _hashInt(int value) { | 1288 static int _hashInt(int value) { |
| 1289 if (value.abs() < _UINT32_LIMIT) return _MASK & value; | 1289 if (value.abs() < _UINT32_LIMIT) return _MASK & value; |
| 1290 return _hashDouble(value.toDouble()); | 1290 return _hashDouble(value.toDouble()); |
| 1291 } | 1291 } |
| 1292 | 1292 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1385 if (!first) { | 1385 if (!first) { |
| 1386 sb.write('_'); | 1386 sb.write('_'); |
| 1387 } | 1387 } |
| 1388 sb.write('_'); | 1388 sb.write('_'); |
| 1389 visit(parameter); | 1389 visit(parameter); |
| 1390 first = true; | 1390 first = true; |
| 1391 } | 1391 } |
| 1392 } | 1392 } |
| 1393 } | 1393 } |
| 1394 } | 1394 } |
| OLD | NEW |