Chromium Code Reviews| Index: lib/compiler/implementation/js_backend/backend.dart |
| diff --git a/lib/compiler/implementation/js_backend/backend.dart b/lib/compiler/implementation/js_backend/backend.dart |
| index d45604ecf16b333015c477b50e1328fe1439b847..6d5ba1ffc5a780ca5d289467e9e0237f77aa3896 100644 |
| --- a/lib/compiler/implementation/js_backend/backend.dart |
| +++ b/lib/compiler/implementation/js_backend/backend.dart |
| @@ -66,6 +66,37 @@ class InvocationInfo { |
| } |
| +class ReturnInfo { |
| + HType returnType; |
| + List<Element> compiledFunctions; |
| + |
| + ReturnInfo(HType this.returnType) |
| + : compiledFunctions = new List<Element>(); |
| + |
| + ReturnInfo.unknownType() |
| + : this.returnType = null, |
| + compiledFunctions = new List<Element>(); |
| + |
| + void update(HType type, var recompile) { |
| + HType newType = returnType != null ? returnType.union(type) : type; |
| + if (newType != returnType) { |
| + if (returnType == null && newType === HType.UNKNOWN) { |
| + // If the first actual piece of information is not providing any type |
| + // information there is no need to recompile callers. |
| + compiledFunctions.clear(); |
| + } |
| + returnType = newType; |
| + if (recompile != null) { |
| + compiledFunctions.forEach(recompile); |
| + } |
| + compiledFunctions.clear(); |
| + } |
| + } |
| + |
| + addCompiledFunction(FunctionElement function) => |
| + compiledFunctions.add(function); |
| +} |
| + |
| class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| final HTypeMap types; |
| @@ -83,6 +114,7 @@ class JavaScriptBackend extends Backend { |
| final Map<Element, InvocationInfo> staticInvocationInfo; |
| final Map<SourceString, Map<Selector, InvocationInfo>> invocationInfo; |
| + final Map<Element, ReturnInfo> returnInfo; |
| final List<Element> invalidateAfterCodegen; |
| @@ -97,6 +129,7 @@ class JavaScriptBackend extends Backend { |
| fieldSettersType = new Map<Element, Map<Element, HType>>(), |
| invocationInfo = new Map<SourceString, Map<Selector, InvocationInfo>>(), |
| staticInvocationInfo = new Map<Element, InvocationInfo>(), |
| + returnInfo = new Map<Element, ReturnInfo>(), |
| invalidateAfterCodegen = new List<Element>(), |
| super(compiler) { |
| builder = new SsaBuilderTask(this); |
| @@ -352,4 +385,36 @@ class JavaScriptBackend extends Backend { |
| return null; |
| } |
| } |
| + |
| + void registerReturnType(FunctionElement element, HType returnType) { |
| + ReturnInfo info = returnInfo[element]; |
| + if (info != null) { |
| + recompile(Element element) { |
| + if (compiler.phase == Compiler.PHASE_COMPILING) { |
| + invalidateAfterCodegen.add(element); |
| + } |
| + } |
| + |
| + info.update(returnType, recompile); |
| + } else { |
| + returnInfo[element] = new ReturnInfo(returnType); |
| + } |
| + } |
| + |
| + /** |
| + * Retreive the return type of the function [calee]. The type is optimistic |
|
ngeoffray
2012/08/17 10:02:51
why not callee?
Søren Gjesse
2012/08/17 10:08:54
Because I cannot spell - fixed.
kasperl
2012/08/17 10:11:07
i before e except after c (Retrieve).
Søren Gjesse
2012/08/17 10:21:04
Done.
|
| + * in the sense that is is based on the compilation og [calee]. If [calee] is |
|
ngeoffray
2012/08/17 10:02:51
og -> of
Søren Gjesse
2012/08/17 10:08:54
Done.
|
| + * recompiled the return type might change to someting broader. For that |
| + * reason [calller] is registered for recompilation if this happens. If the |
|
ngeoffray
2012/08/17 10:02:51
calller -> caller
Søren Gjesse
2012/08/17 10:08:54
Done.
|
| + * function [calee] has not yet been compiled the returned type is [null]. |
| + */ |
| + HType optimisticReturnTypesWithRecompilationOnTypeChange( |
| + FunctionElement caller, FunctionElement calee) { |
| + returnInfo.putIfAbsent(calee, () => new ReturnInfo.unknownType()); |
|
ngeoffray
2012/08/17 10:02:51
Why do you need to put a return info? Could you ju
Søren Gjesse
2012/08/17 10:08:54
The ReturnInfo with returnType null indicates that
|
| + ReturnInfo info = returnInfo[calee]; |
| + if (info.returnType != HType.UNKNOWN && caller != null) { |
| + info.addCompiledFunction(caller); |
| + } |
| + return info.returnType; |
| + } |
| } |