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 typedef void Recompile(Element element); | 5 typedef void Recompile(Element element); |
| 6 | 6 |
| 7 class ReturnInfo { | 7 class ReturnInfo { |
| 8 HType returnType; | 8 HType returnType; |
| 9 List<Element> compiledFunctions; | 9 List<Element> compiledFunctions; |
| 10 | 10 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 compiledFunctions.forEach(recompile); | 28 compiledFunctions.forEach(recompile); |
| 29 } | 29 } |
| 30 compiledFunctions.clear(); | 30 compiledFunctions.clear(); |
| 31 } | 31 } |
| 32 } | 32 } |
| 33 | 33 |
| 34 addCompiledFunction(FunctionElement function) => | 34 addCompiledFunction(FunctionElement function) => |
| 35 compiledFunctions.add(function); | 35 compiledFunctions.add(function); |
| 36 } | 36 } |
| 37 | 37 |
| 38 class OptionalParameterTypes { | |
| 39 final List<SourceString> names; | |
| 40 final List<HType> types; | |
| 41 | |
| 42 OptionalParameterTypes(int optionalArgumentsCount) | |
| 43 : names = new List<SourceString>(optionalArgumentsCount), | |
| 44 types = new List<HType>(optionalArgumentsCount); | |
| 45 | |
| 46 int get length => names.length; | |
| 47 SourceString name(int index) => names[index]; | |
| 48 HType type(int index) => types[index]; | |
| 49 | |
| 50 void insert(int index, SourceString name, HType type) { | |
|
kasperl
2012/09/04 09:18:45
Insert makes it sound like you're growing the list
Søren Gjesse
2012/09/04 14:55:07
Done.
| |
| 51 names[index] = name; | |
| 52 types[index] = type; | |
| 53 } | |
| 54 | |
| 55 String toString() => "OptionalParameterTypes($names, $types)"; | |
| 56 } | |
| 57 | |
| 38 class HTypeList { | 58 class HTypeList { |
| 39 final List<HType> types; | 59 final List<HType> types; |
| 60 final List<SourceString> namedArguments; | |
| 40 | 61 |
| 41 HTypeList(int length) : types = new List<HType>(length); | 62 HTypeList(int length) |
| 42 const HTypeList.allUnknown() : types = null; | 63 : types = new List<HType>(length), |
| 64 namedArguments = null; | |
| 65 HTypeList.withNamedArguments(int length, this.namedArguments) | |
| 66 : types = new List<HType>(length); | |
| 67 const HTypeList.allUnknown() | |
| 68 : types = null, | |
| 69 namedArguments = null; | |
| 43 | 70 |
| 44 factory HTypeList.fromInvocation(HInvoke node, HTypeMap types) { | 71 factory HTypeList.fromStaticInvocation(HInvokeStatic node, HTypeMap types) { |
| 45 bool allUnknown = true; | 72 bool allUnknown = true; |
| 46 for (int i = 1; i < node.inputs.length; i++) { | 73 for (int i = 1; i < node.inputs.length; i++) { |
| 47 if (types[node.inputs[i]] != HType.UNKNOWN) { | 74 if (types[node.inputs[i]] != HType.UNKNOWN) { |
| 48 allUnknown = false; | 75 allUnknown = false; |
| 49 break; | 76 break; |
| 50 } | 77 } |
| 51 } | 78 } |
| 52 if (allUnknown) return HTypeList.ALL_UNKNOWN; | 79 if (allUnknown) return HTypeList.ALL_UNKNOWN; |
| 53 | 80 |
| 54 HTypeList result = new HTypeList(node.inputs.length - 1); | 81 HTypeList result = new HTypeList(node.inputs.length - 1); |
| 55 for (int i = 0; i < result.types.length; i++) { | 82 for (int i = 0; i < result.types.length; i++) { |
| 56 result.types[i] = types[node.inputs[i + 1]]; | 83 result.types[i] = types[node.inputs[i + 1]]; |
| 57 } | 84 } |
| 58 return result; | 85 return result; |
| 59 } | 86 } |
| 60 | 87 |
| 88 factory HTypeList.fromDynamicInvocation(HInvokeDynamic node, | |
| 89 Selector selector, | |
| 90 HTypeMap types) { | |
| 91 HTypeList result; | |
| 92 if (selector.namedArgumentCount > 0) { | |
| 93 result = | |
| 94 new HTypeList.withNamedArguments( | |
| 95 node.inputs.length - 1, selector.namedArguments); | |
|
kasperl
2012/09/04 09:18:45
Maybe cache node.inputs.length - 1 in a local to m
Søren Gjesse
2012/09/04 14:55:07
Done.
| |
| 96 } else { | |
| 97 result = new HTypeList(node.inputs.length - 1); | |
| 98 } | |
| 99 for (int i = 0; i < result.types.length; i++) { | |
| 100 result.types[i] = types[node.inputs[i + 1]]; | |
| 101 } | |
| 102 return result; | |
| 103 } | |
| 104 | |
| 61 static const HTypeList ALL_UNKNOWN = const HTypeList.allUnknown(); | 105 static const HTypeList ALL_UNKNOWN = const HTypeList.allUnknown(); |
| 62 | 106 |
| 63 bool get allUnknown => types === null; | 107 bool get allUnknown => types === null; |
| 108 bool get hasNamedArguments => namedArguments != null; | |
| 64 int get length => types.length; | 109 int get length => types.length; |
| 65 HType operator[](int index) => types[index]; | 110 HType operator[](int index) => types[index]; |
| 66 | 111 |
| 67 HTypeList union(HTypeList other) { | 112 HTypeList union(HTypeList other) { |
| 68 if (allUnknown) return this; | 113 if (allUnknown) return this; |
| 69 if (other.allUnknown) return other; | 114 if (other.allUnknown) return other; |
| 70 if (length != other.length) return HTypeList.ALL_UNKNOWN; | 115 if (length != other.length) return HTypeList.ALL_UNKNOWN; |
| 71 bool onlyUnknown = true; | 116 bool onlyUnknown = true; |
| 72 HTypeList result = this; | 117 HTypeList result = this; |
| 73 for (int i = 0; i < length; i++) { | 118 for (int i = 0; i < length; i++) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 result.types.setRange(0, i, this.types); | 155 result.types.setRange(0, i, this.types); |
| 111 } | 156 } |
| 112 if (result != this) { | 157 if (result != this) { |
| 113 result.types[i] = newType; | 158 result.types[i] = newType; |
| 114 } | 159 } |
| 115 if (result[i] != HType.UNKNOWN) onlyUnknown = false; | 160 if (result[i] != HType.UNKNOWN) onlyUnknown = false; |
| 116 } | 161 } |
| 117 return onlyUnknown ? HTypeList.ALL_UNKNOWN : result; | 162 return onlyUnknown ? HTypeList.ALL_UNKNOWN : result; |
| 118 } | 163 } |
| 119 | 164 |
| 165 HTypeList unionWithOptionalParameters( | |
|
kasperl
2012/09/04 09:18:45
This is fairly complicated. Can you add unit tests
Søren Gjesse
2012/09/04 14:55:07
I tried to do it in tests/compiler/dart2js/backend
| |
| 166 Selector selector, | |
| 167 FunctionSignature signature, | |
| 168 OptionalParameterTypes defaultValueTypes) { | |
| 169 assert(allUnknown || selector.argumentCount == this.length); | |
| 170 // Create a new HTypeList for holding types for all parameters. | |
| 171 HTypeList result = new HTypeList(signature.parameterCount); | |
| 172 | |
| 173 // First fill in the type of the positional arguments. | |
| 174 int nextTypeIndex = -1; | |
| 175 if (allUnknown) { | |
| 176 for (int i = 0; i < selector.positionalArgumentCount; i++) { | |
| 177 result.types[i] = HType.UNKNOWN; | |
| 178 } | |
| 179 } else { | |
| 180 result.types.setRange(0, selector.positionalArgumentCount, this.types); | |
| 181 nextTypeIndex = selector.positionalArgumentCount; | |
| 182 } | |
| 183 int next = selector.positionalArgumentCount; // Next parameter of interest. | |
| 184 int index = signature.requiredParameterCount; // Current parameter. | |
| 185 signature.forEachOptionalParameter((Element element) { | |
| 186 // If some optional parameters where passed positional these have | |
|
kasperl
2012/09/04 09:18:45
positional -> positionally
kasperl
2012/09/04 09:18:45
where -> were
Søren Gjesse
2012/09/04 14:55:07
Done.
Søren Gjesse
2012/09/04 14:55:07
Done.
| |
| 187 // already been filled. | |
| 188 int positionalArgumentCount = selector.positionalArgumentCount; | |
|
kasperl
2012/09/04 09:18:45
This local isn't used.
Søren Gjesse
2012/09/04 14:55:07
Removed.
| |
| 189 if (index == next) { | |
| 190 assert(result.types[index] === null); | |
| 191 HType type = null; | |
| 192 if (selector.namedArgumentCount > 0 && hasNamedArguments) { | |
| 193 for (int i = 0; i < namedArguments.length; i++) { | |
|
kasperl
2012/09/04 09:18:45
Could you use namedArguments.indexOf here? Maybe y
Søren Gjesse
2012/09/04 14:55:07
Nice simplification. Done.
| |
| 194 if (namedArguments[i] == element.name) { | |
| 195 type = types[nextTypeIndex++]; | |
| 196 break; | |
| 197 } | |
| 198 } | |
| 199 } | |
| 200 if (type === null) { | |
| 201 for (int i = 0; i < defaultValueTypes.length; i++) { | |
|
kasperl
2012/09/04 09:18:45
Maybe add indexOf to OptionalParameterTypes?
Søren Gjesse
2012/09/04 14:55:07
Added typeFor(SourceString name) instead.
| |
| 202 if (defaultValueTypes.name(i) == element.name) { | |
| 203 type = defaultValueTypes.type(i); | |
|
kasperl
2012/09/04 09:18:45
If you end up not going for indexOf, you should pr
Søren Gjesse
2012/09/04 14:55:07
See above.
| |
| 204 } | |
| 205 } | |
| 206 } | |
| 207 result.types[index] = type; | |
| 208 next++; | |
| 209 } | |
| 210 index++; | |
| 211 }); | |
| 212 return result; | |
| 213 } | |
| 214 | |
| 120 String toString() => | 215 String toString() => |
| 121 allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types"; | 216 allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types"; |
| 122 } | 217 } |
| 123 | 218 |
| 124 class ArgumentTypesRegistry { | 219 class ArgumentTypesRegistry { |
| 125 final JavaScriptBackend backend; | 220 final JavaScriptBackend backend; |
| 126 final Map<Element, HTypeList> staticTypeMap; | 221 final Map<Element, HTypeList> staticTypeMap; |
| 127 final Set<Element> optimizedStaticFunctions; | 222 final Set<Element> optimizedStaticFunctions; |
| 128 final SelectorMap<HTypeList> selectorTypeMap; | 223 final SelectorMap<HTypeList> selectorTypeMap; |
| 129 final FunctionSet optimizedFunctions; | 224 final FunctionSet optimizedFunctions; |
| 130 final Map<Element, HTypeList> optimizedTypes; | 225 final Map<Element, HTypeList> optimizedTypes; |
| 226 final Map<Element, OptionalParameterTypes> optimizedDefaultValueTypes; | |
| 131 | 227 |
| 132 ArgumentTypesRegistry(JavaScriptBackend backend) | 228 ArgumentTypesRegistry(JavaScriptBackend backend) |
| 133 : staticTypeMap = new Map<Element, HTypeList>(), | 229 : staticTypeMap = new Map<Element, HTypeList>(), |
| 134 optimizedStaticFunctions = new Set<Element>(), | 230 optimizedStaticFunctions = new Set<Element>(), |
| 135 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler), | 231 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler), |
| 136 optimizedFunctions = new FunctionSet(backend.compiler), | 232 optimizedFunctions = new FunctionSet(backend.compiler), |
| 137 optimizedTypes = new Map<Element, HTypeList>(), | 233 optimizedTypes = new Map<Element, HTypeList>(), |
| 234 optimizedDefaultValueTypes = | |
| 235 new Map<Element, OptionalParameterTypes>(), | |
| 138 this.backend = backend; | 236 this.backend = backend; |
| 139 | 237 |
| 140 Compiler get compiler => backend.compiler; | 238 Compiler get compiler => backend.compiler; |
| 141 | 239 |
| 142 // Gather the type information provided. If the types contains no | |
| 143 // useful information there is no need to actually store them. | |
| 144 HTypeList computeProvidedTypes(HInvoke node, HTypeMap types) { | |
| 145 return new HTypeList.fromInvocation(node, types); | |
| 146 } | |
| 147 | |
| 148 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { | 240 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { |
| 149 Element element = node.element; | 241 Element element = node.element; |
| 150 HTypeList oldTypes = staticTypeMap[element]; | 242 HTypeList oldTypes = staticTypeMap[element]; |
| 151 if (oldTypes == null) { | 243 if (oldTypes == null) { |
| 152 staticTypeMap[element] = computeProvidedTypes(node, types); | 244 staticTypeMap[element] = new HTypeList.fromStaticInvocation(node, types); |
| 153 } else { | 245 } else { |
| 154 if (oldTypes.allUnknown) return; | 246 if (oldTypes.allUnknown) return; |
| 155 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); | 247 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); |
| 156 if (newTypes === oldTypes) return; | 248 if (newTypes === oldTypes) return; |
| 157 staticTypeMap[element] = newTypes; | 249 staticTypeMap[element] = newTypes; |
| 158 if (optimizedStaticFunctions.contains(element)) { | 250 if (optimizedStaticFunctions.contains(element)) { |
| 159 backend.scheduleForRecompilation(element); | 251 backend.scheduleForRecompilation(element); |
| 160 } | 252 } |
| 161 } | 253 } |
| 162 } | 254 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 180 // TODO(sgjesse): These checks should use the codegenWorld and keep track | 272 // TODO(sgjesse): These checks should use the codegenWorld and keep track |
| 181 // of changes to this information. | 273 // of changes to this information. |
| 182 Element element = node.element; | 274 Element element = node.element; |
| 183 Universe resolverWorld = compiler.resolverWorld; | 275 Universe resolverWorld = compiler.resolverWorld; |
| 184 if (element != null && | 276 if (element != null && |
| 185 (resolverWorld.hasFieldGetter(element, compiler) || | 277 (resolverWorld.hasFieldGetter(element, compiler) || |
| 186 resolverWorld.hasInvokedGetter(element, compiler))) { | 278 resolverWorld.hasInvokedGetter(element, compiler))) { |
| 187 return; | 279 return; |
| 188 } | 280 } |
| 189 | 281 |
| 190 // TODO(kasperl): For now, we're only dealing with non-named arguments. | 282 HTypeList providedTypes = |
| 191 // We should generalize this. | 283 new HTypeList.fromDynamicInvocation(node, selector, types); |
| 192 HTypeList providedTypes = selector.namedArguments.isEmpty() | |
| 193 ? computeProvidedTypes(node, types) | |
| 194 : HTypeList.ALL_UNKNOWN; | |
| 195 if (!selectorTypeMap.containsKey(selector)) { | 284 if (!selectorTypeMap.containsKey(selector)) { |
| 196 selectorTypeMap[selector] = providedTypes; | 285 selectorTypeMap[selector] = providedTypes; |
| 197 } else { | 286 } else { |
| 198 HTypeList oldTypes = selectorTypeMap[selector]; | 287 HTypeList oldTypes = selectorTypeMap[selector]; |
| 199 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); | 288 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); |
| 200 if (newTypes === oldTypes) return; | 289 if (newTypes === oldTypes) return; |
| 201 selectorTypeMap[selector] = newTypes; | 290 selectorTypeMap[selector] = newTypes; |
| 202 } | 291 } |
| 203 | 292 |
| 204 // If we're not compiling, we don't have to do anything. | 293 // If we're not compiling, we don't have to do anything. |
| 205 if (compiler.phase != Compiler.PHASE_COMPILING) return; | 294 if (compiler.phase != Compiler.PHASE_COMPILING) return; |
| 206 | 295 |
| 207 // Run through all optimized functions and figure out if they need | 296 // Run through all optimized functions and figure out if they need |
| 208 // to be recompiled because of this new invocation. | 297 // to be recompiled because of this new invocation. |
| 209 optimizedFunctions.filterBySelector(selector).forEach((Element element) { | 298 optimizedFunctions.filterBySelector(selector).forEach((Element element) { |
| 210 // TODO(kasperl): Maybe check if the element is already marked for | 299 // TODO(kasperl): Maybe check if the element is already marked for |
| 211 // recompilation? Could be pretty cheap compared to computing | 300 // recompilation? Could be pretty cheap compared to computing |
| 212 // union types. | 301 // union types. |
| 213 HTypeList newTypes = parameterTypes(element); | 302 HTypeList newTypes = |
| 303 parameterTypes(element, optimizedDefaultValueTypes[element]); | |
| 214 bool recompile = false; | 304 bool recompile = false; |
| 215 if (newTypes.allUnknown) { | 305 if (newTypes.allUnknown) { |
| 216 recompile = true; | 306 recompile = true; |
| 217 } else { | 307 } else { |
| 218 HTypeList oldTypes = optimizedTypes[element]; | 308 HTypeList oldTypes = optimizedTypes[element]; |
| 219 if (newTypes.length != oldTypes.length) { | 309 assert(newTypes.length == oldTypes.length); |
|
kasperl
2012/09/04 09:18:45
This is great!
Søren Gjesse
2012/09/04 14:55:07
Thanks.
| |
| 220 // TODO(kasperl): This can be improved. If the newTypes aren't in | 310 for (int i = 0; i < oldTypes.length; i++) { |
| 221 // conflict we can avoid the recompilation. | |
| 222 recompile = true; | |
| 223 } else for (int i = 0; i < oldTypes.length; i++) { | |
| 224 if (newTypes[i] != oldTypes[i]) { | 311 if (newTypes[i] != oldTypes[i]) { |
| 225 recompile = true; | 312 recompile = true; |
| 226 break; | 313 break; |
| 227 } | 314 } |
| 228 } | 315 } |
| 229 } | 316 } |
| 230 if (recompile) backend.scheduleForRecompilation(element); | 317 if (recompile) backend.scheduleForRecompilation(element); |
| 231 }); | 318 }); |
| 232 } | 319 } |
| 233 | 320 |
| 234 HTypeList parameterTypes(element) { | 321 HTypeList parameterTypes(FunctionElement element, |
| 322 OptionalParameterTypes defaultValueTypes) { | |
| 235 // Handle static functions separately. | 323 // Handle static functions separately. |
| 236 if (Elements.isStaticOrTopLevelFunction(element)) { | 324 if (Elements.isStaticOrTopLevelFunction(element)) { |
| 237 HTypeList types = staticTypeMap[element]; | 325 HTypeList types = staticTypeMap[element]; |
| 238 if (types !== null) { | 326 if (types !== null) { |
| 239 if (!optimizedStaticFunctions.contains(element)) { | 327 if (!optimizedStaticFunctions.contains(element)) { |
| 240 optimizedStaticFunctions.add(element); | 328 optimizedStaticFunctions.add(element); |
| 241 } | 329 } |
| 242 return types; | 330 return types; |
| 243 } else { | 331 } else { |
| 244 return HTypeList.ALL_UNKNOWN; | 332 return HTypeList.ALL_UNKNOWN; |
| 245 } | 333 } |
| 246 } | 334 } |
| 247 | 335 |
| 336 | |
| 248 // TODO(kasperl): What kind of non-members do we get here? | 337 // TODO(kasperl): What kind of non-members do we get here? |
| 249 if (!element.isMember()) return HTypeList.ALL_UNKNOWN; | 338 if (!element.isMember()) return HTypeList.ALL_UNKNOWN; |
| 339 if (element.isGetter()) return HTypeList.ALL_UNKNOWN; | |
|
kasperl
2012/09/04 09:18:45
Add a comment that explains why getters should lea
Søren Gjesse
2012/09/04 14:55:07
Done.
| |
| 250 | 340 |
| 251 FunctionSignature signature = element.computeSignature(compiler); | 341 FunctionSignature signature = element.computeSignature(compiler); |
| 252 HTypeList found = null; | 342 HTypeList found = null; |
| 253 selectorTypeMap.visitMatching(element, | 343 selectorTypeMap.visitMatching(element, |
| 254 (Selector selector, HTypeList types) { | 344 (Selector selector, HTypeList types) { |
| 255 if (selector.argumentCount != signature.parameterCount) { | 345 if (selector.argumentCount != signature.parameterCount || |
| 256 found = HTypeList.ALL_UNKNOWN; | 346 selector.namedArgumentCount > 0) { |
| 257 return false; | 347 types = types.unionWithOptionalParameters(selector, |
| 258 } else if (found === null) { | 348 signature, |
|
kasperl
2012/09/04 09:18:45
Indentation is slightly off.
Søren Gjesse
2012/09/04 14:55:07
Done.
Søren Gjesse
2012/09/04 14:55:07
Done.
| |
| 349 defaultValueTypes); | |
| 350 } | |
| 351 assert(types.allUnknown || types.length == signature.parameterCount); | |
| 352 if (found === null) { | |
| 259 found = types; | 353 found = types; |
| 260 return true; | 354 return !found.allUnknown; |
|
kasperl
2012/09/04 09:18:45
This should be shareable now. Something like:
Søren Gjesse
2012/09/04 14:55:07
Done.
| |
| 261 } else { | 355 } else { |
| 262 found = found.union(types); | 356 found = found.union(types); |
| 263 return !found.allUnknown; | 357 return !found.allUnknown; |
| 264 } | 358 } |
| 265 }); | 359 }); |
| 266 return found !== null ? found : HTypeList.ALL_UNKNOWN; | 360 return found !== null ? found : HTypeList.ALL_UNKNOWN; |
| 267 } | 361 } |
| 268 | 362 |
| 269 void registerOptimization(Element element, HTypeList parameterTypes) { | 363 void registerOptimization(Element element, |
| 364 HTypeList parameterTypes, | |
| 365 OptionalParameterTypes defaultValueTypes) { | |
| 270 if (Elements.isStaticOrTopLevelFunction(element)) { | 366 if (Elements.isStaticOrTopLevelFunction(element)) { |
| 271 if (parameterTypes.allUnknown) { | 367 if (parameterTypes.allUnknown) { |
| 272 optimizedStaticFunctions.remove(element); | 368 optimizedStaticFunctions.remove(element); |
| 273 } else { | 369 } else { |
| 274 optimizedStaticFunctions.add(element); | 370 optimizedStaticFunctions.add(element); |
| 275 } | 371 } |
| 276 } | 372 } |
| 277 | 373 |
| 278 // TODO(kasperl): What kind of non-members do we get here? | 374 // TODO(kasperl): What kind of non-members do we get here? |
| 279 if (!element.isMember()) return; | 375 if (!element.isMember()) return; |
| 280 | 376 |
| 281 if (parameterTypes.allUnknown) { | 377 if (parameterTypes.allUnknown) { |
| 282 optimizedFunctions.remove(element); | 378 optimizedFunctions.remove(element); |
| 283 optimizedTypes.remove(element); | 379 optimizedTypes.remove(element); |
| 380 optimizedDefaultValueTypes.remove(element); | |
| 284 } else { | 381 } else { |
| 285 optimizedFunctions.add(element); | 382 optimizedFunctions.add(element); |
| 286 optimizedTypes[element] = parameterTypes; | 383 optimizedTypes[element] = parameterTypes; |
| 384 optimizedDefaultValueTypes[element] = defaultValueTypes; | |
| 287 } | 385 } |
| 288 } | 386 } |
| 289 } | 387 } |
| 290 | 388 |
| 291 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 389 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 292 final HTypeMap types; | 390 final HTypeMap types; |
| 293 | 391 |
| 294 JavaScriptItemCompilationContext() : types = new HTypeMap(); | 392 JavaScriptItemCompilationContext() : types = new HTypeMap(); |
| 295 } | 393 } |
| 296 | 394 |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 */ | 596 */ |
| 499 void registerNonCallStaticUse(HStatic node) { | 597 void registerNonCallStaticUse(HStatic node) { |
| 500 argumentTypes.registerNonCallStaticUse(node); | 598 argumentTypes.registerNonCallStaticUse(node); |
| 501 } | 599 } |
| 502 | 600 |
| 503 /** | 601 /** |
| 504 * Retrieve the types of the parameters used for calling the [element] | 602 * Retrieve the types of the parameters used for calling the [element] |
| 505 * function. The types are optimistic in the sense as they are based on the | 603 * function. The types are optimistic in the sense as they are based on the |
| 506 * possible invocations of the function seen so far. | 604 * possible invocations of the function seen so far. |
| 507 */ | 605 */ |
| 508 HTypeList optimisticParameterTypes(FunctionElement element) { | 606 HTypeList optimisticParameterTypes( |
| 509 return argumentTypes.parameterTypes(element); | 607 FunctionElement element, |
| 608 OptionalParameterTypes defaultValueTypes) { | |
| 609 return argumentTypes.parameterTypes(element, defaultValueTypes); | |
| 510 } | 610 } |
| 511 | 611 |
| 512 /** | 612 /** |
| 513 * Register that the function [element] has been optimized under the | 613 * Register that the function [element] has been optimized under the |
| 514 * assumptions that the types [parameterType] will be used for calling it. | 614 * assumptions that the types [parameterType] will be used for calling it. |
| 515 * If this assumption fail the function will be scheduled for recompilation. | 615 * The passed [defaultValueTypes] holds the types of default values for |
| 616 * the optional parameters. If this assumption fail the function will be | |
| 617 * scheduled for recompilation. | |
| 516 */ | 618 */ |
| 517 registerParameterTypesOptimization( | 619 registerParameterTypesOptimization( |
| 518 FunctionElement element, HTypeList parameterTypes) { | 620 FunctionElement element, |
| 519 argumentTypes.registerOptimization(element, parameterTypes); | 621 HTypeList parameterTypes, |
|
kasperl
2012/09/04 09:18:45
I wonder if we should have an abstraction over all
Søren Gjesse
2012/09/04 14:55:07
That might be - I will look at that as a separate
| |
| 622 OptionalParameterTypes defaultValueTypes) { | |
| 623 argumentTypes.registerOptimization( | |
| 624 element, parameterTypes, defaultValueTypes); | |
| 520 } | 625 } |
| 521 | 626 |
| 522 void registerReturnType(FunctionElement element, HType returnType) { | 627 void registerReturnType(FunctionElement element, HType returnType) { |
| 523 ReturnInfo info = returnInfo[element]; | 628 ReturnInfo info = returnInfo[element]; |
| 524 if (info != null) { | 629 if (info != null) { |
| 525 info.update(returnType, scheduleForRecompilation); | 630 info.update(returnType, scheduleForRecompilation); |
| 526 } else { | 631 } else { |
| 527 returnInfo[element] = new ReturnInfo(returnType); | 632 returnInfo[element] = new ReturnInfo(returnType); |
| 528 } | 633 } |
| 529 } | 634 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 577 return const SourceString('listSuperTypeCheck'); | 682 return const SourceString('listSuperTypeCheck'); |
| 578 } | 683 } |
| 579 } else if (nativeCheck) { | 684 } else if (nativeCheck) { |
| 580 return const SourceString('callTypeCheck'); | 685 return const SourceString('callTypeCheck'); |
| 581 } else { | 686 } else { |
| 582 return const SourceString('propertyTypeCheck'); | 687 return const SourceString('propertyTypeCheck'); |
| 583 } | 688 } |
| 584 } | 689 } |
| 585 } | 690 } |
| 586 } | 691 } |
| OLD | NEW |