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 class InvocationInfo { | 5 class InvocationInfo { |
| 6 int parameterCount = -1; | 6 int parameterCount = -1; |
| 7 List<HType> providedTypes; | 7 List<HType> providedTypes; |
| 8 List<Element> compiledFunctions; | 8 List<Element> compiledFunctions; |
| 9 | 9 |
| 10 InvocationInfo(HInvoke node, HTypeMap types) | 10 InvocationInfo(HInvoke node, HTypeMap types) |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 InvocationInfo.unknownTypes(); | 31 InvocationInfo.unknownTypes(); |
| 32 | 32 |
| 33 void update(HInvoke node, HTypeMap types, var recompile) { | 33 void update(HInvoke node, HTypeMap types, var recompile) { |
| 34 // If we don't know anything useful about the types adding more | 34 // If we don't know anything useful about the types adding more |
| 35 // information will not help. | 35 // information will not help. |
| 36 if (!hasTypeInformation) return; | 36 if (!hasTypeInformation) return; |
| 37 | 37 |
| 38 // Update the type information with the provided types. | 38 // Update the type information with the provided types. |
| 39 bool typesChanged = false; | 39 bool typesChanged = false; |
| 40 bool allUnknown = true; | 40 bool allUnknown = true; |
| 41 for (int i = 0; i < providedTypes.length; i++) { | 41 |
| 42 HType newType = providedTypes[i].union(types[node.inputs[i + 1]]); | 42 if (providedTypes.length != node.inputs.length - 1) { |
| 43 if (newType != providedTypes[i]) { | 43 // If the signatures don't match, remove all optimizations on |
| 44 typesChanged = true; | 44 // that selector. |
| 45 providedTypes[i] = newType; | 45 typesChanged = true; |
|
Søren Gjesse
2012/08/23 10:37:09
Maybe add
allUnknown = true
here for clarity.
ngeoffray
2012/08/23 12:30:19
Done.
| |
| 46 } else { | |
| 47 for (int i = 0; i < providedTypes.length; i++) { | |
| 48 HType newType = providedTypes[i].union(types[node.inputs[i + 1]]); | |
| 49 if (newType != providedTypes[i]) { | |
| 50 typesChanged = true; | |
| 51 providedTypes[i] = newType; | |
| 52 } | |
| 53 if (providedTypes[i] != HType.UNKNOWN) allUnknown = false; | |
| 46 } | 54 } |
| 47 if (providedTypes[i] != HType.UNKNOWN) allUnknown = false; | |
| 48 } | 55 } |
| 49 // If the provided types change we need to recompile all functions which | 56 // If the provided types change we need to recompile all functions which |
| 50 // have been compiled under the now invalidated assumptions. | 57 // have been compiled under the now invalidated assumptions. |
| 51 if (typesChanged && compiledFunctions.length != 0) { | 58 if (typesChanged && compiledFunctions.length != 0) { |
| 52 if (recompile != null) { | 59 if (recompile != null) { |
| 53 compiledFunctions.forEach(recompile); | 60 compiledFunctions.forEach(recompile); |
| 54 } | 61 } |
| 55 compiledFunctions.clear(); | 62 compiledFunctions.clear(); |
| 56 } | 63 } |
| 57 // If all information is lost no need to keep it around. | 64 // If all information is lost no need to keep it around. |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 /** | 288 /** |
| 282 * Register a dynamic invocation and collect the provided types for the | 289 * Register a dynamic invocation and collect the provided types for the |
| 283 * named selector. | 290 * named selector. |
| 284 */ | 291 */ |
| 285 void registerDynamicInvocation(HInvokeDynamicMethod node, | 292 void registerDynamicInvocation(HInvokeDynamicMethod node, |
| 286 Selector selector, | 293 Selector selector, |
| 287 HTypeMap types) { | 294 HTypeMap types) { |
| 288 Map<Selector, InvocationInfo> invocationInfos = | 295 Map<Selector, InvocationInfo> invocationInfos = |
| 289 invocationInfo.putIfAbsent(selector.name, | 296 invocationInfo.putIfAbsent(selector.name, |
| 290 () => new Map<Selector, InvocationInfo>()); | 297 () => new Map<Selector, InvocationInfo>()); |
| 291 InvocationInfo info = invocationInfos[selector]; | 298 if (!invocationInfos.isEmpty()) { |
| 292 if (info != null) { | 299 invocationInfos.forEach((Selector _, InvocationInfo info) { |
| 293 void recompile(Element element) { | 300 // TODO(ngeoffray): Check that the signature of [info] applies to |
| 294 if (compiler.phase == Compiler.PHASE_COMPILING) { | 301 // [element]. We cannot do that right now because the |
| 295 invalidateAfterCodegen.add(element); | 302 // strategy is all or nothing. We should actually retain the |
| 303 // methods that don't apply to [selector]. | |
| 304 void recompile(Element element) { | |
| 305 if (compiler.phase == Compiler.PHASE_COMPILING) { | |
| 306 invalidateAfterCodegen.add(element); | |
| 307 } | |
| 296 } | 308 } |
| 297 } | |
| 298 | 309 |
| 299 info.update(node, types, recompile); | 310 info.update(node, types, recompile); |
| 311 }); | |
| 300 } else { | 312 } else { |
| 301 invocationInfos[selector] = new InvocationInfo(node, types); | 313 invocationInfos[selector] = new InvocationInfo(node, types); |
| 302 } | 314 } |
| 303 } | 315 } |
| 304 | 316 |
| 305 /** | 317 /** |
| 306 * Register a static invocation and collect the provided types for the | 318 * Register a static invocation and collect the provided types for the |
| 307 * named selector. | 319 * named selector. |
| 308 */ | 320 */ |
| 309 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { | 321 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 HType optimisticReturnTypesWithRecompilationOnTypeChange( | 423 HType optimisticReturnTypesWithRecompilationOnTypeChange( |
| 412 FunctionElement caller, FunctionElement callee) { | 424 FunctionElement caller, FunctionElement callee) { |
| 413 returnInfo.putIfAbsent(callee, () => new ReturnInfo.unknownType()); | 425 returnInfo.putIfAbsent(callee, () => new ReturnInfo.unknownType()); |
| 414 ReturnInfo info = returnInfo[callee]; | 426 ReturnInfo info = returnInfo[callee]; |
| 415 if (info.returnType != HType.UNKNOWN && caller != null) { | 427 if (info.returnType != HType.UNKNOWN && caller != null) { |
| 416 info.addCompiledFunction(caller); | 428 info.addCompiledFunction(caller); |
| 417 } | 429 } |
| 418 return info.returnType; | 430 return info.returnType; |
| 419 } | 431 } |
| 420 } | 432 } |
| OLD | NEW |