Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
| index 2f9027256c28141316bef0ff9df50c1c58f8176a..14913dd5bc88d3147bb255c4355470d95a810b8b 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
| @@ -122,6 +122,49 @@ class MalformedCheckedModeHelper extends CheckedModeHelper { |
| } |
| } |
| +/* |
| + * Invariants: |
| + * canInline(function) implies canInline(function, insideLoop:true) |
| + * !canInline(function, insideLoop: true) implies !canInline(function) |
| + */ |
| +class FunctionInlineCache { |
| + final Map<FunctionElement, bool> canBeInlined = |
| + new Map<FunctionElement, bool>(); |
| + |
| + final Map<FunctionElement, bool> canBeInlinedInsideLoop = |
| + new Map<FunctionElement, bool>(); |
| + |
| + // Returns [:true:]/[:false:] if we have a cached decision. |
| + // Returns [:null:] otherwise. |
| + bool canInline(FunctionElement element, {bool insideLoop: false}) { |
|
ngeoffray
2013/07/16 08:04:45
I'd drop the default value: it reads easier if all
kustermann
2013/07/16 13:27:50
Done.
|
| + if (insideLoop) |
| + return canBeInlinedInsideLoop[element]; |
| + return canBeInlined[element]; |
|
ngeoffray
2013/07/16 08:04:45
nit: use return insideLoop ? ... : ...;
kustermann
2013/07/16 13:27:50
Done.
|
| + } |
| + |
| + void markAsInlinable(FunctionElement element, {bool insideLoop: false}) { |
|
ngeoffray
2013/07/16 08:04:45
ditto for insideLoop argument.
kustermann
2013/07/16 13:27:50
Done.
|
| + if (insideLoop) { |
| + canBeInlinedInsideLoop[element] = true; |
| + } else { |
| + // If we can inline a function outside a loop then we should do it inside |
| + // a loop as well. |
| + canBeInlined[element] = true; |
| + canBeInlinedInsideLoop[element] = true; |
| + } |
| + } |
| + |
| + void markAsNonInlinable(FunctionElement element, {bool insideLoop: false}) { |
|
ngeoffray
2013/07/16 08:04:45
ditto.
kustermann
2013/07/16 13:27:50
Done.
|
| + if (insideLoop) { |
| + // If we can't inline a function inside a loop, then we should not inline |
| + // it outside a loop either. |
| + canBeInlined[element] = false; |
| + canBeInlinedInsideLoop[element] = false; |
| + } else { |
| + canBeInlined[element] = false; |
| + } |
| + } |
| +} |
| + |
| class JavaScriptBackend extends Backend { |
| SsaBuilderTask builder; |
| @@ -142,12 +185,7 @@ class JavaScriptBackend extends Backend { |
| final Map<Element, jsAst.Expression> generatedBailoutCode = |
| new Map<Element, jsAst.Expression>(); |
| - /** |
| - * Keep track of which function elements are simple enough to be |
| - * inlined in callers. |
| - */ |
| - final Map<FunctionElement, bool> canBeInlined = |
| - new Map<FunctionElement, bool>(); |
| + FunctionInlineCache inlineCache = new FunctionInlineCache(); |
| ClassElement jsInterceptorClass; |
| ClassElement jsStringClass; |
| @@ -436,9 +474,9 @@ class JavaScriptBackend extends Backend { |
| compiler.findHelper(const SourceString('defineNativeMethodsFinish')); |
| // These methods are overwritten with generated versions. |
| - canBeInlined[getInterceptorMethod] = false; |
| - canBeInlined[getDispatchPropertyMethod] = false; |
| - canBeInlined[setDispatchPropertyMethod] = false; |
| + inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true); |
| + inlineCache.markAsNonInlinable(getDispatchPropertyMethod, insideLoop: true); |
| + inlineCache.markAsNonInlinable(setDispatchPropertyMethod, insideLoop: true); |
| List<ClassElement> classes = [ |
| jsInterceptorClass = |