| 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 typedef void Recompile(Element element); | 7 typedef void Recompile(Element element); |
| 8 | 8 |
| 9 class ReturnInfo { | 9 class ReturnInfo { |
| 10 HType returnType; | 10 HType returnType; |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 constructors.putIfAbsent(cls, () => new Set<Element>()); | 299 constructors.putIfAbsent(cls, () => new Set<Element>()); |
| 300 Set<Element> ctors = constructors[cls]; | 300 Set<Element> ctors = constructors[cls]; |
| 301 if (ctors.contains(element)) return; | 301 if (ctors.contains(element)) return; |
| 302 ctors.add(element); | 302 ctors.add(element); |
| 303 // We cannot infer field types for classes with more than one constructor. | 303 // We cannot infer field types for classes with more than one constructor. |
| 304 // When the second constructor is seen, recompile all functions relying on | 304 // When the second constructor is seen, recompile all functions relying on |
| 305 // optimistic field types for that class. | 305 // optimistic field types for that class. |
| 306 // TODO(sgjesse): Handle field types for classes with more than one | 306 // TODO(sgjesse): Handle field types for classes with more than one |
| 307 // constructor. | 307 // constructor. |
| 308 if (ctors.length == 2) { | 308 if (ctors.length == 2) { |
| 309 new Map.from(optimizedFunctions).forEach((Element field, _) { | 309 optimizedFunctions.forEach((Element field, _) { |
| 310 if (identical(field.enclosingElement, cls)) { | 310 if (identical(field.enclosingElement, cls)) { |
| 311 scheduleRecompilation(field); | 311 scheduleRecompilation(field); |
| 312 } | 312 } |
| 313 }); | 313 }); |
| 314 } | 314 } |
| 315 } | 315 } |
| 316 | 316 |
| 317 void registerFieldInitializer(Element field, HType type) { | 317 void registerFieldInitializer(Element field, HType type) { |
| 318 registerFieldType(fieldInitializerTypeMap, field, type); | 318 registerFieldType(fieldInitializerTypeMap, field, type); |
| 319 } | 319 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 340 registerFieldType(fieldTypeMap, field, type); | 340 registerFieldType(fieldTypeMap, field, type); |
| 341 } | 341 } |
| 342 | 342 |
| 343 void addedDynamicSetter(Selector setter, HType type) { | 343 void addedDynamicSetter(Selector setter, HType type) { |
| 344 // Field type optimizations are disabled for all fields matching a | 344 // Field type optimizations are disabled for all fields matching a |
| 345 // setter selector. | 345 // setter selector. |
| 346 assert(setter.isSetter()); | 346 assert(setter.isSetter()); |
| 347 // TODO(sgjesse): Take the type of the setter into account. | 347 // TODO(sgjesse): Take the type of the setter into account. |
| 348 if (setterSelectorsUsed.contains(setter.name)) return; | 348 if (setterSelectorsUsed.contains(setter.name)) return; |
| 349 setterSelectorsUsed.add(setter.name); | 349 setterSelectorsUsed.add(setter.name); |
| 350 new Map.from(optimizedStaticFunctions).forEach((Element field, _) { | 350 optimizedStaticFunctions.forEach((Element field, _) { |
| 351 if (field.name == setter.name) { | 351 if (field.name == setter.name) { |
| 352 scheduleRecompilation(field); | 352 scheduleRecompilation(field); |
| 353 } | 353 } |
| 354 }); | 354 }); |
| 355 new Map.from(optimizedFunctions).forEach((Element field, _) { | 355 optimizedFunctions.forEach((Element field, _) { |
| 356 if (field.name == setter.name) { | 356 if (field.name == setter.name) { |
| 357 scheduleRecompilation(field); | 357 scheduleRecompilation(field); |
| 358 } | 358 } |
| 359 }); | 359 }); |
| 360 } | 360 } |
| 361 | 361 |
| 362 HType optimisticFieldType(Element field) { | 362 HType optimisticFieldType(Element field) { |
| 363 assert(field.isField()); | 363 assert(field.isField()); |
| 364 if (constructorCount(field.getEnclosingClass()) > 1) { | 364 if (constructorCount(field.getEnclosingClass()) > 1) { |
| 365 return HType.UNKNOWN; | 365 return HType.UNKNOWN; |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 boundsChecked = new Set<HInstruction>(); | 615 boundsChecked = new Set<HInstruction>(); |
| 616 } | 616 } |
| 617 | 617 |
| 618 class JavaScriptBackend extends Backend { | 618 class JavaScriptBackend extends Backend { |
| 619 SsaBuilderTask builder; | 619 SsaBuilderTask builder; |
| 620 SsaOptimizerTask optimizer; | 620 SsaOptimizerTask optimizer; |
| 621 SsaCodeGeneratorTask generator; | 621 SsaCodeGeneratorTask generator; |
| 622 CodeEmitterTask emitter; | 622 CodeEmitterTask emitter; |
| 623 | 623 |
| 624 /** | 624 /** |
| 625 * The generated code as a js AST for compiled methods. | 625 * The generated code as a js AST for compiled methods. |
| 626 */ | 626 */ |
| 627 Map<Element, js.Expression> get generatedCode { | 627 Map<Element, js.Expression> get generatedCode { |
| 628 return compiler.enqueuer.codegen.generatedCode; | 628 return compiler.enqueuer.codegen.generatedCode; |
| 629 } | 629 } |
| 630 | 630 |
| 631 /** | 631 /** |
| 632 * The generated code as a js AST for compiled bailout methods. | 632 * The generated code as a js AST for compiled bailout methods. |
| 633 */ | 633 */ |
| 634 final Map<Element, js.Expression> generatedBailoutCode = | 634 final Map<Element, js.Expression> generatedBailoutCode = |
| 635 new Map<Element, js.Expression>(); | 635 new Map<Element, js.Expression>(); |
| 636 | 636 |
| 637 ClassElement jsStringClass; | 637 ClassElement jsStringClass; |
| 638 ClassElement jsArrayClass; | 638 ClassElement jsArrayClass; |
| 639 ClassElement jsNumberClass; | 639 ClassElement jsNumberClass; |
| 640 ClassElement jsIntClass; | 640 ClassElement jsIntClass; |
| 641 ClassElement jsDoubleClass; | 641 ClassElement jsDoubleClass; |
| 642 ClassElement jsFunctionClass; | 642 ClassElement jsFunctionClass; |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 } else if (cls == compiler.nullClass) { | 901 } else if (cls == compiler.nullClass) { |
| 902 addInterceptors(jsNullClass, enqueuer); | 902 addInterceptors(jsNullClass, enqueuer); |
| 903 } else if (cls == compiler.numClass) { | 903 } else if (cls == compiler.numClass) { |
| 904 addInterceptors(jsIntClass, enqueuer); | 904 addInterceptors(jsIntClass, enqueuer); |
| 905 addInterceptors(jsDoubleClass, enqueuer); | 905 addInterceptors(jsDoubleClass, enqueuer); |
| 906 addInterceptors(jsNumberClass, enqueuer); | 906 addInterceptors(jsNumberClass, enqueuer); |
| 907 } else if (cls == compiler.mapClass) { | 907 } else if (cls == compiler.mapClass) { |
| 908 // The backend will use a literal list to initialize the entries | 908 // The backend will use a literal list to initialize the entries |
| 909 // of the map. | 909 // of the map. |
| 910 if (enqueuer.isResolutionQueue) { | 910 if (enqueuer.isResolutionQueue) { |
| 911 enqueuer.registerInstantiatedClass(compiler.listClass); | 911 enqueuer.registerInstantiatedClass(compiler.listClass); |
| 912 enqueuer.registerInstantiatedClass(compiler.mapLiteralClass); | 912 enqueuer.registerInstantiatedClass(compiler.mapLiteralClass); |
| 913 } | 913 } |
| 914 } | 914 } |
| 915 } | 915 } |
| 916 | 916 |
| 917 Element get cyclicThrowHelper { | 917 Element get cyclicThrowHelper { |
| 918 return compiler.findHelper(const SourceString("throwCyclicInit")); | 918 return compiler.findHelper(const SourceString("throwCyclicInit")); |
| 919 } | 919 } |
| 920 | 920 |
| 921 JavaScriptItemCompilationContext createItemCompilationContext() { | 921 JavaScriptItemCompilationContext createItemCompilationContext() { |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 * | 1256 * |
| 1257 * Invariant: [element] must be a declaration element. | 1257 * Invariant: [element] must be a declaration element. |
| 1258 */ | 1258 */ |
| 1259 void eagerRecompile(Element element) { | 1259 void eagerRecompile(Element element) { |
| 1260 assert(invariant(element, element.isDeclaration)); | 1260 assert(invariant(element, element.isDeclaration)); |
| 1261 generatedCode.remove(element); | 1261 generatedCode.remove(element); |
| 1262 generatedBailoutCode.remove(element); | 1262 generatedBailoutCode.remove(element); |
| 1263 compiler.enqueuer.codegen.addToWorkList(element); | 1263 compiler.enqueuer.codegen.addToWorkList(element); |
| 1264 } | 1264 } |
| 1265 } | 1265 } |
| OLD | NEW |