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 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 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 : types = new HTypeMap(), | 614 : types = new HTypeMap(), |
| 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 /** | |
| 625 * The generated code as a js AST for compiled methods. | |
|
karlklose
2013/02/08 11:44:53
'js' -> 'JavaScript' or 'JS'
| |
| 626 */ | |
| 627 Map<Element, js.Expression> get generatedCode { | |
| 628 return compiler.enqueuer.codegen.generatedCode; | |
| 629 } | |
| 630 | |
| 631 /** | |
| 632 * The generated code as a js AST for compiled bailout methods. | |
|
karlklose
2013/02/08 11:44:53
ditto.
| |
| 633 */ | |
| 634 final Map<Element, js.Expression> generatedBailoutCode = | |
| 635 new Map<Element, js.Expression>(); | |
| 636 | |
| 624 ClassElement jsStringClass; | 637 ClassElement jsStringClass; |
| 625 ClassElement jsArrayClass; | 638 ClassElement jsArrayClass; |
| 626 ClassElement jsNumberClass; | 639 ClassElement jsNumberClass; |
| 627 ClassElement jsIntClass; | 640 ClassElement jsIntClass; |
| 628 ClassElement jsDoubleClass; | 641 ClassElement jsDoubleClass; |
| 629 ClassElement jsFunctionClass; | 642 ClassElement jsFunctionClass; |
| 630 ClassElement jsNullClass; | 643 ClassElement jsNullClass; |
| 631 ClassElement jsBoolClass; | 644 ClassElement jsBoolClass; |
| 632 ClassElement objectInterceptorClass; | 645 ClassElement objectInterceptorClass; |
| 633 Element jsArrayLength; | 646 Element jsArrayLength; |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 921 | 934 |
| 922 for (var helper in [const SourceString('Closure'), | 935 for (var helper in [const SourceString('Closure'), |
| 923 const SourceString('ConstantMap'), | 936 const SourceString('ConstantMap'), |
| 924 const SourceString('ConstantProtoMap')]) { | 937 const SourceString('ConstantProtoMap')]) { |
| 925 var e = compiler.findHelper(helper); | 938 var e = compiler.findHelper(helper); |
| 926 if (e != null) world.registerInstantiatedClass(e); | 939 if (e != null) world.registerInstantiatedClass(e); |
| 927 } | 940 } |
| 928 } | 941 } |
| 929 | 942 |
| 930 void codegen(CodegenWorkItem work) { | 943 void codegen(CodegenWorkItem work) { |
| 931 if (work.element.kind.category == ElementCategory.VARIABLE) { | 944 Element element = work.element; |
| 945 if (element.kind.category == ElementCategory.VARIABLE) { | |
| 932 Constant initialValue = compiler.constantHandler.compileWorkItem(work); | 946 Constant initialValue = compiler.constantHandler.compileWorkItem(work); |
| 933 if (initialValue != null) { | 947 if (initialValue != null) { |
| 934 return; | 948 return; |
| 935 } else { | 949 } else { |
| 936 // If the constant-handler was not able to produce a result we have to | 950 // If the constant-handler was not able to produce a result we have to |
| 937 // go through the builder (below) to generate the lazy initializer for | 951 // go through the builder (below) to generate the lazy initializer for |
| 938 // the static variable. | 952 // the static variable. |
| 939 // We also need to register the use of the cyclic-error helper. | 953 // We also need to register the use of the cyclic-error helper. |
| 940 compiler.enqueuer.codegen.registerStaticUse(cyclicThrowHelper); | 954 compiler.enqueuer.codegen.registerStaticUse(cyclicThrowHelper); |
| 941 } | 955 } |
| 942 } | 956 } |
| 943 | 957 |
| 944 HGraph graph = builder.build(work); | 958 HGraph graph = builder.build(work); |
| 945 optimizer.optimize(work, graph, false); | 959 optimizer.optimize(work, graph, false); |
| 946 if (work.allowSpeculativeOptimization | 960 if (work.allowSpeculativeOptimization |
| 947 && optimizer.trySpeculativeOptimizations(work, graph)) { | 961 && optimizer.trySpeculativeOptimizations(work, graph)) { |
| 948 js.Expression code = generator.generateBailoutMethod(work, graph); | 962 js.Expression code = generator.generateBailoutMethod(work, graph); |
| 949 compiler.codegenWorld.addBailoutCode(work, code); | 963 generatedBailoutCode[element] = code; |
| 950 optimizer.prepareForSpeculativeOptimizations(work, graph); | 964 optimizer.prepareForSpeculativeOptimizations(work, graph); |
| 951 optimizer.optimize(work, graph, true); | 965 optimizer.optimize(work, graph, true); |
| 952 } | 966 } |
| 953 js.Expression code = generator.generateCode(work, graph); | 967 js.Expression code = generator.generateCode(work, graph); |
| 954 compiler.codegenWorld.addGeneratedCode(work, code); | 968 generatedCode[element] = code; |
| 955 invalidateAfterCodegen.forEach(compiler.enqueuer.codegen.eagerRecompile); | 969 invalidateAfterCodegen.forEach(eagerRecompile); |
| 956 invalidateAfterCodegen.clear(); | 970 invalidateAfterCodegen.clear(); |
| 957 } | 971 } |
| 958 | 972 |
| 959 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { | 973 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { |
| 960 return new native.NativeResolutionEnqueuer(world, compiler); | 974 return new native.NativeResolutionEnqueuer(world, compiler); |
| 961 } | 975 } |
| 962 | 976 |
| 963 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { | 977 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { |
| 964 return new native.NativeCodegenEnqueuer(world, compiler, emitter); | 978 return new native.NativeCodegenEnqueuer(world, compiler, emitter); |
| 965 } | 979 } |
| 966 | 980 |
| 981 /** | |
| 982 * Unit test hook that returns code of an element as a String. | |
| 983 * | |
| 984 * Invariant: [element] must be a declaration element. | |
| 985 */ | |
| 986 String assembleCode(Element element) { | |
| 987 assert(invariant(element, element.isDeclaration)); | |
| 988 return js.prettyPrint(generatedCode[element], compiler).getText(); | |
| 989 } | |
| 990 | |
| 967 void assembleProgram() { | 991 void assembleProgram() { |
| 968 emitter.assembleProgram(); | 992 emitter.assembleProgram(); |
| 969 } | 993 } |
| 970 | 994 |
| 971 /** | 995 /** |
| 972 * Documentation wanted -- johnniwinther | 996 * Documentation wanted -- johnniwinther |
| 973 * | 997 * |
| 974 * Invariant: [element] must be a declaration element. | 998 * Invariant: [element] must be a declaration element. |
| 975 */ | 999 */ |
| 976 void scheduleForRecompilation(Element element) { | 1000 void scheduleForRecompilation(Element element) { |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1215 return compiler.findHelper(const SourceString('makeLiteralMap')); | 1239 return compiler.findHelper(const SourceString('makeLiteralMap')); |
| 1216 } | 1240 } |
| 1217 | 1241 |
| 1218 Element getSetRuntimeTypeInfo() { | 1242 Element getSetRuntimeTypeInfo() { |
| 1219 return compiler.findHelper(const SourceString('setRuntimeTypeInfo')); | 1243 return compiler.findHelper(const SourceString('setRuntimeTypeInfo')); |
| 1220 } | 1244 } |
| 1221 | 1245 |
| 1222 Element getGetRuntimeTypeInfo() { | 1246 Element getGetRuntimeTypeInfo() { |
| 1223 return compiler.findHelper(const SourceString('getRuntimeTypeInfo')); | 1247 return compiler.findHelper(const SourceString('getRuntimeTypeInfo')); |
| 1224 } | 1248 } |
| 1249 | |
| 1250 /** | |
| 1251 * Remove [element] from the set of generated code, and put it back | |
| 1252 * into the worklist. | |
| 1253 * | |
| 1254 * Invariant: [element] must be a declaration element. | |
| 1255 */ | |
| 1256 void eagerRecompile(Element element) { | |
| 1257 assert(invariant(element, element.isDeclaration)); | |
| 1258 generatedCode.remove(element); | |
| 1259 generatedBailoutCode.remove(element); | |
| 1260 compiler.enqueuer.codegen.addToWorkList(element); | |
| 1261 } | |
| 1225 } | 1262 } |
| OLD | NEW |