| 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 part of js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 8 final Set<HInstruction> boundsChecked; | 8 final Set<HInstruction> boundsChecked; |
| 9 | 9 |
| 10 JavaScriptItemCompilationContext() | 10 JavaScriptItemCompilationContext() |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 List<jsAst.Expression> arguments) { | 115 List<jsAst.Expression> arguments) { |
| 116 DartType type = node.typeExpression; | 116 DartType type = node.typeExpression; |
| 117 assert(type.isMalformed); | 117 assert(type.isMalformed); |
| 118 String reasons = Types.fetchReasonsFromMalformedType(type); | 118 String reasons = Types.fetchReasonsFromMalformedType(type); |
| 119 arguments.add(js.string('$type')); | 119 arguments.add(js.string('$type')); |
| 120 // TODO(johnniwinther): Handle escaping correctly. | 120 // TODO(johnniwinther): Handle escaping correctly. |
| 121 arguments.add(js.string(reasons)); | 121 arguments.add(js.string(reasons)); |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 | 124 |
| 125 /* |
| 126 * Invariants: |
| 127 * canInline(function) implies canInline(function, insideLoop:true) |
| 128 * !canInline(function, insideLoop: true) implies !canInline(function) |
| 129 */ |
| 130 class FunctionInlineCache { |
| 131 final Map<FunctionElement, bool> canBeInlined = |
| 132 new Map<FunctionElement, bool>(); |
| 133 |
| 134 final Map<FunctionElement, bool> canBeInlinedInsideLoop = |
| 135 new Map<FunctionElement, bool>(); |
| 136 |
| 137 // Returns [:true:]/[:false:] if we have a cached decision. |
| 138 // Returns [:null:] otherwise. |
| 139 bool canInline(FunctionElement element, {bool insideLoop}) { |
| 140 return insideLoop ? canBeInlinedInsideLoop[element] : canBeInlined[element]; |
| 141 } |
| 142 |
| 143 void markAsInlinable(FunctionElement element, {bool insideLoop}) { |
| 144 if (insideLoop) { |
| 145 canBeInlinedInsideLoop[element] = true; |
| 146 } else { |
| 147 // If we can inline a function outside a loop then we should do it inside |
| 148 // a loop as well. |
| 149 canBeInlined[element] = true; |
| 150 canBeInlinedInsideLoop[element] = true; |
| 151 } |
| 152 } |
| 153 |
| 154 void markAsNonInlinable(FunctionElement element, {bool insideLoop}) { |
| 155 if (insideLoop) { |
| 156 // If we can't inline a function inside a loop, then we should not inline |
| 157 // it outside a loop either. |
| 158 canBeInlined[element] = false; |
| 159 canBeInlinedInsideLoop[element] = false; |
| 160 } else { |
| 161 canBeInlined[element] = false; |
| 162 } |
| 163 } |
| 164 } |
| 165 |
| 125 | 166 |
| 126 class JavaScriptBackend extends Backend { | 167 class JavaScriptBackend extends Backend { |
| 127 SsaBuilderTask builder; | 168 SsaBuilderTask builder; |
| 128 SsaOptimizerTask optimizer; | 169 SsaOptimizerTask optimizer; |
| 129 SsaCodeGeneratorTask generator; | 170 SsaCodeGeneratorTask generator; |
| 130 CodeEmitterTask emitter; | 171 CodeEmitterTask emitter; |
| 131 | 172 |
| 132 /** | 173 /** |
| 133 * The generated code as a js AST for compiled methods. | 174 * The generated code as a js AST for compiled methods. |
| 134 */ | 175 */ |
| 135 Map<Element, jsAst.Expression> get generatedCode { | 176 Map<Element, jsAst.Expression> get generatedCode { |
| 136 return compiler.enqueuer.codegen.generatedCode; | 177 return compiler.enqueuer.codegen.generatedCode; |
| 137 } | 178 } |
| 138 | 179 |
| 139 /** | 180 /** |
| 140 * The generated code as a js AST for compiled bailout methods. | 181 * The generated code as a js AST for compiled bailout methods. |
| 141 */ | 182 */ |
| 142 final Map<Element, jsAst.Expression> generatedBailoutCode = | 183 final Map<Element, jsAst.Expression> generatedBailoutCode = |
| 143 new Map<Element, jsAst.Expression>(); | 184 new Map<Element, jsAst.Expression>(); |
| 144 | 185 |
| 145 /** | 186 FunctionInlineCache inlineCache = new FunctionInlineCache(); |
| 146 * Keep track of which function elements are simple enough to be | |
| 147 * inlined in callers. | |
| 148 */ | |
| 149 final Map<FunctionElement, bool> canBeInlined = | |
| 150 new Map<FunctionElement, bool>(); | |
| 151 | 187 |
| 152 ClassElement jsInterceptorClass; | 188 ClassElement jsInterceptorClass; |
| 153 ClassElement jsStringClass; | 189 ClassElement jsStringClass; |
| 154 ClassElement jsArrayClass; | 190 ClassElement jsArrayClass; |
| 155 ClassElement jsNumberClass; | 191 ClassElement jsNumberClass; |
| 156 ClassElement jsIntClass; | 192 ClassElement jsIntClass; |
| 157 ClassElement jsDoubleClass; | 193 ClassElement jsDoubleClass; |
| 158 ClassElement jsNullClass; | 194 ClassElement jsNullClass; |
| 159 ClassElement jsBoolClass; | 195 ClassElement jsBoolClass; |
| 160 ClassElement jsUnknownClass; | 196 ClassElement jsUnknownClass; |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 compiler.findInterceptor(const SourceString('setDispatchProperty')); | 465 compiler.findInterceptor(const SourceString('setDispatchProperty')); |
| 430 getNativeInterceptorMethod = | 466 getNativeInterceptorMethod = |
| 431 compiler.findInterceptor(const SourceString('getNativeInterceptor')); | 467 compiler.findInterceptor(const SourceString('getNativeInterceptor')); |
| 432 initializeDispatchPropertyMethod = | 468 initializeDispatchPropertyMethod = |
| 433 compiler.findInterceptor( | 469 compiler.findInterceptor( |
| 434 new SourceString(emitter.nameOfDispatchPropertyInitializer)); | 470 new SourceString(emitter.nameOfDispatchPropertyInitializer)); |
| 435 defineNativeMethodsFinishMethod = | 471 defineNativeMethodsFinishMethod = |
| 436 compiler.findHelper(const SourceString('defineNativeMethodsFinish')); | 472 compiler.findHelper(const SourceString('defineNativeMethodsFinish')); |
| 437 | 473 |
| 438 // These methods are overwritten with generated versions. | 474 // These methods are overwritten with generated versions. |
| 439 canBeInlined[getInterceptorMethod] = false; | 475 inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true); |
| 440 canBeInlined[getDispatchPropertyMethod] = false; | 476 inlineCache.markAsNonInlinable(getDispatchPropertyMethod, insideLoop: true); |
| 441 canBeInlined[setDispatchPropertyMethod] = false; | 477 inlineCache.markAsNonInlinable(setDispatchPropertyMethod, insideLoop: true); |
| 442 | 478 |
| 443 List<ClassElement> classes = [ | 479 List<ClassElement> classes = [ |
| 444 jsInterceptorClass = | 480 jsInterceptorClass = |
| 445 compiler.findInterceptor(const SourceString('Interceptor')), | 481 compiler.findInterceptor(const SourceString('Interceptor')), |
| 446 jsStringClass = compiler.findInterceptor(const SourceString('JSString')), | 482 jsStringClass = compiler.findInterceptor(const SourceString('JSString')), |
| 447 jsArrayClass = compiler.findInterceptor(const SourceString('JSArray')), | 483 jsArrayClass = compiler.findInterceptor(const SourceString('JSArray')), |
| 448 // The int class must be before the double class, because the | 484 // The int class must be before the double class, because the |
| 449 // emitter relies on this list for the order of type checks. | 485 // emitter relies on this list for the order of type checks. |
| 450 jsIntClass = compiler.findInterceptor(const SourceString('JSInt')), | 486 jsIntClass = compiler.findInterceptor(const SourceString('JSInt')), |
| 451 jsDoubleClass = compiler.findInterceptor(const SourceString('JSDouble')), | 487 jsDoubleClass = compiler.findInterceptor(const SourceString('JSDouble')), |
| (...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1442 } | 1478 } |
| 1443 } | 1479 } |
| 1444 | 1480 |
| 1445 /// Records that [type] is used by [user.element]. | 1481 /// Records that [type] is used by [user.element]. |
| 1446 class Dependency { | 1482 class Dependency { |
| 1447 final DartType type; | 1483 final DartType type; |
| 1448 final TreeElements user; | 1484 final TreeElements user; |
| 1449 | 1485 |
| 1450 const Dependency(this.type, this.user); | 1486 const Dependency(this.type, this.user); |
| 1451 } | 1487 } |
| OLD | NEW |