| 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 18 matching lines...) Expand all Loading... |
| 29 } | 29 } |
| 30 compiledFunctions.clear(); | 30 compiledFunctions.clear(); |
| 31 } | 31 } |
| 32 } | 32 } |
| 33 | 33 |
| 34 // Note that lazy initializers are treated like functions (but are not | 34 // Note that lazy initializers are treated like functions (but are not |
| 35 // of type [FunctionElement]. | 35 // of type [FunctionElement]. |
| 36 addCompiledFunction(Element function) => compiledFunctions.add(function); | 36 addCompiledFunction(Element function) => compiledFunctions.add(function); |
| 37 } | 37 } |
| 38 | 38 |
| 39 class OptionalParameterTypes { |
| 40 final List<SourceString> names; |
| 41 final List<HType> types; |
| 42 |
| 43 OptionalParameterTypes(int optionalArgumentsCount) |
| 44 : names = new List<SourceString>(optionalArgumentsCount), |
| 45 types = new List<HType>(optionalArgumentsCount); |
| 46 |
| 47 int get length => names.length; |
| 48 SourceString name(int index) => names[index]; |
| 49 HType type(int index) => types[index]; |
| 50 int indexOf(SourceString name) => names.indexOf(name); |
| 51 |
| 52 HType typeFor(SourceString name) { |
| 53 int index = indexOf(name); |
| 54 if (index == -1) return null; |
| 55 return type(index); |
| 56 } |
| 57 |
| 58 void update(int index, SourceString name, HType type) { |
| 59 names[index] = name; |
| 60 types[index] = type; |
| 61 } |
| 62 |
| 63 String toString() => "OptionalParameterTypes($names, $types)"; |
| 64 } |
| 65 |
| 39 class HTypeList { | 66 class HTypeList { |
| 40 final List<HType> types; | 67 final List<HType> types; |
| 68 final List<SourceString> namedArguments; |
| 41 | 69 |
| 42 HTypeList(int length) : types = new List<HType>(length); | 70 HTypeList(int length) |
| 43 const HTypeList.withAllUnknown() : types = null; | 71 : types = new List<HType>(length), |
| 72 namedArguments = null; |
| 73 HTypeList.withNamedArguments(int length, this.namedArguments) |
| 74 : types = new List<HType>(length); |
| 75 const HTypeList.allUnknown() |
| 76 : types = null, |
| 77 namedArguments = null; |
| 44 | 78 |
| 45 factory HTypeList.fromInvocation(HInvoke node, HTypeMap types) { | 79 factory HTypeList.fromStaticInvocation(HInvokeStatic node, HTypeMap types) { |
| 46 bool allUnknown = true; | 80 bool allUnknown = true; |
| 47 for (int i = 1; i < node.inputs.length; i++) { | 81 for (int i = 1; i < node.inputs.length; i++) { |
| 48 if (types[node.inputs[i]] != HType.UNKNOWN) { | 82 if (types[node.inputs[i]] != HType.UNKNOWN) { |
| 49 allUnknown = false; | 83 allUnknown = false; |
| 50 break; | 84 break; |
| 51 } | 85 } |
| 52 } | 86 } |
| 53 if (allUnknown) return HTypeList.ALL_UNKNOWN; | 87 if (allUnknown) return HTypeList.ALL_UNKNOWN; |
| 54 | 88 |
| 55 HTypeList result = new HTypeList(node.inputs.length - 1); | 89 HTypeList result = new HTypeList(node.inputs.length - 1); |
| 56 for (int i = 0; i < result.types.length; i++) { | 90 for (int i = 0; i < result.types.length; i++) { |
| 57 result.types[i] = types[node.inputs[i + 1]]; | 91 result.types[i] = types[node.inputs[i + 1]]; |
| 58 } | 92 } |
| 59 return result; | 93 return result; |
| 60 } | 94 } |
| 61 | 95 |
| 62 static const HTypeList ALL_UNKNOWN = const HTypeList.withAllUnknown(); | 96 factory HTypeList.fromDynamicInvocation(HInvokeDynamic node, |
| 97 Selector selector, |
| 98 HTypeMap types) { |
| 99 HTypeList result; |
| 100 int argumentsCount = node.inputs.length - 1; |
| 101 if (selector.namedArgumentCount > 0) { |
| 102 result = |
| 103 new HTypeList.withNamedArguments( |
| 104 argumentsCount, selector.namedArguments); |
| 105 } else { |
| 106 result = new HTypeList(argumentsCount); |
| 107 } |
| 108 for (int i = 0; i < result.types.length; i++) { |
| 109 result.types[i] = types[node.inputs[i + 1]]; |
| 110 } |
| 111 return result; |
| 112 } |
| 113 |
| 114 static const HTypeList ALL_UNKNOWN = const HTypeList.allUnknown(); |
| 63 | 115 |
| 64 bool get allUnknown => types === null; | 116 bool get allUnknown => types === null; |
| 117 bool get hasNamedArguments => namedArguments != null; |
| 65 int get length => types.length; | 118 int get length => types.length; |
| 66 HType operator[](int index) => types[index]; | 119 HType operator[](int index) => types[index]; |
| 67 | 120 |
| 68 HTypeList union(HTypeList other) { | 121 HTypeList union(HTypeList other) { |
| 69 if (allUnknown) return this; | 122 if (allUnknown) return this; |
| 70 if (other.allUnknown) return other; | 123 if (other.allUnknown) return other; |
| 71 if (length != other.length) return HTypeList.ALL_UNKNOWN; | 124 if (length != other.length) return HTypeList.ALL_UNKNOWN; |
| 72 bool onlyUnknown = true; | 125 bool onlyUnknown = true; |
| 73 HTypeList result = this; | 126 HTypeList result = this; |
| 74 for (int i = 0; i < length; i++) { | 127 for (int i = 0; i < length; i++) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 result.types.setRange(0, i, this.types); | 164 result.types.setRange(0, i, this.types); |
| 112 } | 165 } |
| 113 if (result != this) { | 166 if (result != this) { |
| 114 result.types[i] = newType; | 167 result.types[i] = newType; |
| 115 } | 168 } |
| 116 if (result[i] != HType.UNKNOWN) onlyUnknown = false; | 169 if (result[i] != HType.UNKNOWN) onlyUnknown = false; |
| 117 } | 170 } |
| 118 return onlyUnknown ? HTypeList.ALL_UNKNOWN : result; | 171 return onlyUnknown ? HTypeList.ALL_UNKNOWN : result; |
| 119 } | 172 } |
| 120 | 173 |
| 174 HTypeList unionWithOptionalParameters( |
| 175 Selector selector, |
| 176 FunctionSignature signature, |
| 177 OptionalParameterTypes defaultValueTypes) { |
| 178 assert(allUnknown || selector.argumentCount == this.length); |
| 179 // Create a new HTypeList for holding types for all parameters. |
| 180 HTypeList result = new HTypeList(signature.parameterCount); |
| 181 |
| 182 // First fill in the type of the positional arguments. |
| 183 int nextTypeIndex = -1; |
| 184 if (allUnknown) { |
| 185 for (int i = 0; i < selector.positionalArgumentCount; i++) { |
| 186 result.types[i] = HType.UNKNOWN; |
| 187 } |
| 188 } else { |
| 189 result.types.setRange(0, selector.positionalArgumentCount, this.types); |
| 190 nextTypeIndex = selector.positionalArgumentCount; |
| 191 } |
| 192 |
| 193 // Next fill the type of the optional arguments. |
| 194 // As the selector can pass optional arguments positionally some of the |
| 195 // optional arguments might already have a type set. We only need to look |
| 196 // at the optional arguments not passed positionally. |
| 197 // The variable 'index' is counting the signatures optional arguments, the |
| 198 // variable 'next' is set to the next optional arguments to look at and |
| 199 // is used to skip some optional arguments. |
| 200 int next = selector.positionalArgumentCount; |
| 201 int index = signature.requiredParameterCount; |
| 202 signature.forEachOptionalParameter((Element element) { |
| 203 // If some optional parameters were passed positionally these have |
| 204 // already been filled. |
| 205 if (index == next) { |
| 206 assert(result.types[index] === null); |
| 207 HType type = null; |
| 208 if (hasNamedArguments && |
| 209 selector.namedArguments.indexOf(element.name) >= 0) { |
| 210 type = types[nextTypeIndex++]; |
| 211 } else { |
| 212 type = defaultValueTypes.typeFor(element.name); |
| 213 } |
| 214 result.types[index] = type; |
| 215 next++; |
| 216 } |
| 217 index++; |
| 218 }); |
| 219 return result; |
| 220 } |
| 221 |
| 121 String toString() => | 222 String toString() => |
| 122 allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types"; | 223 allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types"; |
| 123 } | 224 } |
| 124 | 225 |
| 125 class ArgumentTypesRegistry { | 226 class ArgumentTypesRegistry { |
| 126 final JavaScriptBackend backend; | 227 final JavaScriptBackend backend; |
| 127 final Map<Element, HTypeList> staticTypeMap; | 228 final Map<Element, HTypeList> staticTypeMap; |
| 128 final Set<Element> optimizedStaticFunctions; | 229 final Set<Element> optimizedStaticFunctions; |
| 129 final SelectorMap<HTypeList> selectorTypeMap; | 230 final SelectorMap<HTypeList> selectorTypeMap; |
| 130 final FunctionSet optimizedFunctions; | 231 final FunctionSet optimizedFunctions; |
| 131 final Map<Element, HTypeList> optimizedTypes; | 232 final Map<Element, HTypeList> optimizedTypes; |
| 233 final Map<Element, OptionalParameterTypes> optimizedDefaultValueTypes; |
| 132 | 234 |
| 133 ArgumentTypesRegistry(JavaScriptBackend backend) | 235 ArgumentTypesRegistry(JavaScriptBackend backend) |
| 134 : staticTypeMap = new Map<Element, HTypeList>(), | 236 : staticTypeMap = new Map<Element, HTypeList>(), |
| 135 optimizedStaticFunctions = new Set<Element>(), | 237 optimizedStaticFunctions = new Set<Element>(), |
| 136 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler), | 238 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler), |
| 137 optimizedFunctions = new FunctionSet(backend.compiler), | 239 optimizedFunctions = new FunctionSet(backend.compiler), |
| 138 optimizedTypes = new Map<Element, HTypeList>(), | 240 optimizedTypes = new Map<Element, HTypeList>(), |
| 241 optimizedDefaultValueTypes = |
| 242 new Map<Element, OptionalParameterTypes>(), |
| 139 this.backend = backend; | 243 this.backend = backend; |
| 140 | 244 |
| 141 Compiler get compiler => backend.compiler; | 245 Compiler get compiler => backend.compiler; |
| 142 | 246 |
| 143 // Gather the type information provided. If the types contains no | |
| 144 // useful information there is no need to actually store them. | |
| 145 HTypeList computeProvidedTypes(HInvoke node, HTypeMap types) { | |
| 146 return new HTypeList.fromInvocation(node, types); | |
| 147 } | |
| 148 | |
| 149 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { | 247 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { |
| 150 Element element = node.element; | 248 Element element = node.element; |
| 151 HTypeList oldTypes = staticTypeMap[element]; | 249 HTypeList oldTypes = staticTypeMap[element]; |
| 152 if (oldTypes == null) { | 250 if (oldTypes == null) { |
| 153 staticTypeMap[element] = computeProvidedTypes(node, types); | 251 staticTypeMap[element] = new HTypeList.fromStaticInvocation(node, types); |
| 154 } else { | 252 } else { |
| 155 if (oldTypes.allUnknown) return; | 253 if (oldTypes.allUnknown) return; |
| 156 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); | 254 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); |
| 157 if (newTypes === oldTypes) return; | 255 if (newTypes === oldTypes) return; |
| 158 staticTypeMap[element] = newTypes; | 256 staticTypeMap[element] = newTypes; |
| 159 if (optimizedStaticFunctions.contains(element)) { | 257 if (optimizedStaticFunctions.contains(element)) { |
| 160 backend.scheduleForRecompilation(element); | 258 backend.scheduleForRecompilation(element); |
| 161 } | 259 } |
| 162 } | 260 } |
| 163 } | 261 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 181 // TODO(sgjesse): These checks should use the codegenWorld and keep track | 279 // TODO(sgjesse): These checks should use the codegenWorld and keep track |
| 182 // of changes to this information. | 280 // of changes to this information. |
| 183 Element element = node.element; | 281 Element element = node.element; |
| 184 Universe resolverWorld = compiler.resolverWorld; | 282 Universe resolverWorld = compiler.resolverWorld; |
| 185 if (element != null && | 283 if (element != null && |
| 186 (resolverWorld.hasFieldGetter(element, compiler) || | 284 (resolverWorld.hasFieldGetter(element, compiler) || |
| 187 resolverWorld.hasInvokedGetter(element, compiler))) { | 285 resolverWorld.hasInvokedGetter(element, compiler))) { |
| 188 return; | 286 return; |
| 189 } | 287 } |
| 190 | 288 |
| 191 // TODO(kasperl): For now, we're only dealing with non-named arguments. | 289 HTypeList providedTypes = |
| 192 // We should generalize this. | 290 new HTypeList.fromDynamicInvocation(node, selector, types); |
| 193 HTypeList providedTypes = selector.namedArguments.isEmpty() | |
| 194 ? computeProvidedTypes(node, types) | |
| 195 : HTypeList.ALL_UNKNOWN; | |
| 196 if (!selectorTypeMap.containsKey(selector)) { | 291 if (!selectorTypeMap.containsKey(selector)) { |
| 197 selectorTypeMap[selector] = providedTypes; | 292 selectorTypeMap[selector] = providedTypes; |
| 198 } else { | 293 } else { |
| 199 HTypeList oldTypes = selectorTypeMap[selector]; | 294 HTypeList oldTypes = selectorTypeMap[selector]; |
| 200 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); | 295 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); |
| 201 if (newTypes === oldTypes) return; | 296 if (newTypes === oldTypes) return; |
| 202 selectorTypeMap[selector] = newTypes; | 297 selectorTypeMap[selector] = newTypes; |
| 203 } | 298 } |
| 204 | 299 |
| 205 // If we're not compiling, we don't have to do anything. | 300 // If we're not compiling, we don't have to do anything. |
| 206 if (compiler.phase != Compiler.PHASE_COMPILING) return; | 301 if (compiler.phase != Compiler.PHASE_COMPILING) return; |
| 207 | 302 |
| 208 // Run through all optimized functions and figure out if they need | 303 // Run through all optimized functions and figure out if they need |
| 209 // to be recompiled because of this new invocation. | 304 // to be recompiled because of this new invocation. |
| 210 optimizedFunctions.filterBySelector(selector).forEach((Element element) { | 305 optimizedFunctions.filterBySelector(selector).forEach((Element element) { |
| 211 // TODO(kasperl): Maybe check if the element is already marked for | 306 // TODO(kasperl): Maybe check if the element is already marked for |
| 212 // recompilation? Could be pretty cheap compared to computing | 307 // recompilation? Could be pretty cheap compared to computing |
| 213 // union types. | 308 // union types. |
| 214 HTypeList newTypes = parameterTypes(element); | 309 HTypeList newTypes = |
| 310 parameterTypes(element, optimizedDefaultValueTypes[element]); |
| 215 bool recompile = false; | 311 bool recompile = false; |
| 216 if (newTypes.allUnknown) { | 312 if (newTypes.allUnknown) { |
| 217 recompile = true; | 313 recompile = true; |
| 218 } else { | 314 } else { |
| 219 HTypeList oldTypes = optimizedTypes[element]; | 315 HTypeList oldTypes = optimizedTypes[element]; |
| 220 if (newTypes.length != oldTypes.length) { | 316 assert(newTypes.length == oldTypes.length); |
| 221 // TODO(kasperl): This can be improved. If the newTypes aren't in | 317 for (int i = 0; i < oldTypes.length; i++) { |
| 222 // conflict we can avoid the recompilation. | |
| 223 recompile = true; | |
| 224 } else for (int i = 0; i < oldTypes.length; i++) { | |
| 225 if (newTypes[i] != oldTypes[i]) { | 318 if (newTypes[i] != oldTypes[i]) { |
| 226 recompile = true; | 319 recompile = true; |
| 227 break; | 320 break; |
| 228 } | 321 } |
| 229 } | 322 } |
| 230 } | 323 } |
| 231 if (recompile) backend.scheduleForRecompilation(element); | 324 if (recompile) backend.scheduleForRecompilation(element); |
| 232 }); | 325 }); |
| 233 } | 326 } |
| 234 | 327 |
| 235 HTypeList parameterTypes(element) { | 328 HTypeList parameterTypes(FunctionElement element, |
| 329 OptionalParameterTypes defaultValueTypes) { |
| 236 // Handle static functions separately. | 330 // Handle static functions separately. |
| 237 if (Elements.isStaticOrTopLevelFunction(element)) { | 331 if (Elements.isStaticOrTopLevelFunction(element)) { |
| 238 HTypeList types = staticTypeMap[element]; | 332 HTypeList types = staticTypeMap[element]; |
| 239 if (types !== null) { | 333 if (types !== null) { |
| 240 if (!optimizedStaticFunctions.contains(element)) { | 334 if (!optimizedStaticFunctions.contains(element)) { |
| 241 optimizedStaticFunctions.add(element); | 335 optimizedStaticFunctions.add(element); |
| 242 } | 336 } |
| 243 return types; | 337 return types; |
| 244 } else { | 338 } else { |
| 245 return HTypeList.ALL_UNKNOWN; | 339 return HTypeList.ALL_UNKNOWN; |
| 246 } | 340 } |
| 247 } | 341 } |
| 248 | 342 |
| 343 // Getters have no parameters. |
| 344 if (element.isGetter()) return HTypeList.ALL_UNKNOWN; |
| 345 |
| 249 // TODO(kasperl): What kind of non-members do we get here? | 346 // TODO(kasperl): What kind of non-members do we get here? |
| 250 if (!element.isMember()) return HTypeList.ALL_UNKNOWN; | 347 if (!element.isMember()) return HTypeList.ALL_UNKNOWN; |
| 251 | 348 |
| 252 FunctionSignature signature = element.computeSignature(compiler); | 349 FunctionSignature signature = element.computeSignature(compiler); |
| 253 HTypeList found = null; | 350 HTypeList found = null; |
| 254 selectorTypeMap.visitMatching(element, | 351 selectorTypeMap.visitMatching(element, |
| 255 (Selector selector, HTypeList types) { | 352 (Selector selector, HTypeList types) { |
| 256 if (selector.argumentCount != signature.parameterCount) { | 353 if (selector.argumentCount != signature.parameterCount || |
| 257 found = HTypeList.ALL_UNKNOWN; | 354 selector.namedArgumentCount > 0) { |
| 258 return false; | 355 types = types.unionWithOptionalParameters(selector, |
| 259 } else if (found === null) { | 356 signature, |
| 260 found = types; | 357 defaultValueTypes); |
| 261 return true; | |
| 262 } else { | |
| 263 found = found.union(types); | |
| 264 return !found.allUnknown; | |
| 265 } | 358 } |
| 359 assert(types.allUnknown || types.length == signature.parameterCount); |
| 360 found = (found === null) ? types : found.union(types); |
| 361 return !found.allUnknown; |
| 266 }); | 362 }); |
| 267 return found !== null ? found : HTypeList.ALL_UNKNOWN; | 363 return found !== null ? found : HTypeList.ALL_UNKNOWN; |
| 268 } | 364 } |
| 269 | 365 |
| 270 void registerOptimization(Element element, HTypeList parameterTypes) { | 366 void registerOptimization(Element element, |
| 367 HTypeList parameterTypes, |
| 368 OptionalParameterTypes defaultValueTypes) { |
| 271 if (Elements.isStaticOrTopLevelFunction(element)) { | 369 if (Elements.isStaticOrTopLevelFunction(element)) { |
| 272 if (parameterTypes.allUnknown) { | 370 if (parameterTypes.allUnknown) { |
| 273 optimizedStaticFunctions.remove(element); | 371 optimizedStaticFunctions.remove(element); |
| 274 } else { | 372 } else { |
| 275 optimizedStaticFunctions.add(element); | 373 optimizedStaticFunctions.add(element); |
| 276 } | 374 } |
| 277 } | 375 } |
| 278 | 376 |
| 279 // TODO(kasperl): What kind of non-members do we get here? | 377 // TODO(kasperl): What kind of non-members do we get here? |
| 280 if (!element.isMember()) return; | 378 if (!element.isMember()) return; |
| 281 | 379 |
| 282 if (parameterTypes.allUnknown) { | 380 if (parameterTypes.allUnknown) { |
| 283 optimizedFunctions.remove(element); | 381 optimizedFunctions.remove(element); |
| 284 optimizedTypes.remove(element); | 382 optimizedTypes.remove(element); |
| 383 optimizedDefaultValueTypes.remove(element); |
| 285 } else { | 384 } else { |
| 286 optimizedFunctions.add(element); | 385 optimizedFunctions.add(element); |
| 287 optimizedTypes[element] = parameterTypes; | 386 optimizedTypes[element] = parameterTypes; |
| 387 optimizedDefaultValueTypes[element] = defaultValueTypes; |
| 288 } | 388 } |
| 289 } | 389 } |
| 290 } | 390 } |
| 291 | 391 |
| 292 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 392 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 293 final HTypeMap types; | 393 final HTypeMap types; |
| 294 | 394 |
| 295 JavaScriptItemCompilationContext() : types = new HTypeMap(); | 395 JavaScriptItemCompilationContext() : types = new HTypeMap(); |
| 296 } | 396 } |
| 297 | 397 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 */ | 615 */ |
| 516 void registerNonCallStaticUse(HStatic node) { | 616 void registerNonCallStaticUse(HStatic node) { |
| 517 argumentTypes.registerNonCallStaticUse(node); | 617 argumentTypes.registerNonCallStaticUse(node); |
| 518 } | 618 } |
| 519 | 619 |
| 520 /** | 620 /** |
| 521 * Retrieve the types of the parameters used for calling the [element] | 621 * Retrieve the types of the parameters used for calling the [element] |
| 522 * function. The types are optimistic in the sense as they are based on the | 622 * function. The types are optimistic in the sense as they are based on the |
| 523 * possible invocations of the function seen so far. | 623 * possible invocations of the function seen so far. |
| 524 */ | 624 */ |
| 525 HTypeList optimisticParameterTypes(FunctionElement element) { | 625 HTypeList optimisticParameterTypes( |
| 526 return argumentTypes.parameterTypes(element); | 626 FunctionElement element, |
| 627 OptionalParameterTypes defaultValueTypes) { |
| 628 return argumentTypes.parameterTypes(element, defaultValueTypes); |
| 527 } | 629 } |
| 528 | 630 |
| 529 /** | 631 /** |
| 530 * Register that the function [element] has been optimized under the | 632 * Register that the function [element] has been optimized under the |
| 531 * assumptions that the types [parameterType] will be used for calling it. | 633 * assumptions that the types [parameterType] will be used for calling it. |
| 532 * If this assumption fail the function will be scheduled for recompilation. | 634 * The passed [defaultValueTypes] holds the types of default values for |
| 635 * the optional parameters. If this assumption fail the function will be |
| 636 * scheduled for recompilation. |
| 533 */ | 637 */ |
| 534 registerParameterTypesOptimization( | 638 registerParameterTypesOptimization( |
| 535 FunctionElement element, HTypeList parameterTypes) { | 639 FunctionElement element, |
| 536 argumentTypes.registerOptimization(element, parameterTypes); | 640 HTypeList parameterTypes, |
| 641 OptionalParameterTypes defaultValueTypes) { |
| 642 argumentTypes.registerOptimization( |
| 643 element, parameterTypes, defaultValueTypes); |
| 537 } | 644 } |
| 538 | 645 |
| 539 void registerReturnType(FunctionElement element, HType returnType) { | 646 void registerReturnType(FunctionElement element, HType returnType) { |
| 540 ReturnInfo info = returnInfo[element]; | 647 ReturnInfo info = returnInfo[element]; |
| 541 if (info != null) { | 648 if (info != null) { |
| 542 info.update(returnType, scheduleForRecompilation); | 649 info.update(returnType, scheduleForRecompilation); |
| 543 } else { | 650 } else { |
| 544 returnInfo[element] = new ReturnInfo(returnType); | 651 returnInfo[element] = new ReturnInfo(returnType); |
| 545 } | 652 } |
| 546 } | 653 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 return const SourceString('listSuperTypeCheck'); | 701 return const SourceString('listSuperTypeCheck'); |
| 595 } | 702 } |
| 596 } else if (nativeCheck) { | 703 } else if (nativeCheck) { |
| 597 return const SourceString('callTypeCheck'); | 704 return const SourceString('callTypeCheck'); |
| 598 } else { | 705 } else { |
| 599 return const SourceString('propertyTypeCheck'); | 706 return const SourceString('propertyTypeCheck'); |
| 600 } | 707 } |
| 601 } | 708 } |
| 602 } | 709 } |
| 603 } | 710 } |
| OLD | NEW |