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