| 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 class SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
| 6 final JavaScriptBackend backend; | 6 final JavaScriptBackend backend; |
| 7 SsaCodeGeneratorTask(JavaScriptBackend backend) | 7 SsaCodeGeneratorTask(JavaScriptBackend backend) |
| 8 : this.backend = backend, | 8 : this.backend = backend, |
| 9 super(backend.compiler); | 9 super(backend.compiler); |
| 10 String get name() => 'SSA code generator'; | 10 String get name() => 'SSA code generator'; |
| 11 NativeEmitter get nativeEmitter() => backend.emitter.nativeEmitter; | 11 NativeEmitter get nativeEmitter() => backend.emitter.nativeEmitter; |
| 12 | 12 |
| 13 | 13 |
| 14 js.Fun buildJavaScriptFunction(FunctionElement element, | 14 js.Fun buildJavaScriptFunction(FunctionElement element, |
| 15 List<js.Parameter> parameters, | 15 List<js.Parameter> parameters, |
| 16 js.Block body) { | 16 js.Block body) { |
| 17 FunctionExpression expression = element.cachedNode; | 17 FunctionExpression expression = element.cachedNode; |
| 18 js.Fun result = new js.Fun(parameters, body); | 18 js.Fun result = new js.Fun(parameters, body); |
| 19 result.sourcePosition = expression.getBeginToken(); | 19 result.sourcePosition = expression.getBeginToken(); |
| 20 result.endSourcePosition = expression.getEndToken(); | 20 result.endSourcePosition = expression.getEndToken(); |
| 21 return result; | 21 return result; |
| 22 } | 22 } |
| 23 | 23 |
| 24 CodeBuffer prettyPrint(js.Node node, Element positionElement) { | 24 CodeBuffer prettyPrint(js.Node node, Element positionElement) { |
| 25 return js.prettyPrint(node, compiler, positionElement); | 25 return js.prettyPrint(node, compiler, positionElement); |
| 26 } | 26 } |
| 27 | 27 |
| 28 CodeBuffer generateCode(WorkItem work, HGraph graph) { |
| 29 if (work.element.isField()) { |
| 30 return generateLazyInitializer(work, graph); |
| 31 } else { |
| 32 return generateMethod(work, graph); |
| 33 } |
| 34 } |
| 35 |
| 36 CodeBuffer generateLazyInitializer(work, graph) { |
| 37 return measure(() { |
| 38 compiler.tracer.traceGraph("codegen", graph); |
| 39 List<js.Parameter> parameters = <js.Parameter>[]; |
| 40 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( |
| 41 backend, work, parameters, new Map<Element, String>()); |
| 42 codegen.visitGraph(graph); |
| 43 js.Block body = codegen.body; |
| 44 Element element = work.element; |
| 45 js.Fun fun = new js.Fun(parameters, body); |
| 46 return prettyPrint(fun, element); |
| 47 }); |
| 48 } |
| 49 |
| 28 CodeBuffer generateMethod(WorkItem work, HGraph graph) { | 50 CodeBuffer generateMethod(WorkItem work, HGraph graph) { |
| 29 return measure(() { | 51 return measure(() { |
| 30 compiler.tracer.traceGraph("codegen", graph); | 52 compiler.tracer.traceGraph("codegen", graph); |
| 31 Map<Element, String> parameterNames = getParameterNames(work); | 53 Map<Element, String> parameterNames = getParameterNames(work); |
| 32 parameterNames.forEach((element, name) { | 54 parameterNames.forEach((element, name) { |
| 33 compiler.enqueuer.codegen.addToWorkList(element); | 55 compiler.enqueuer.codegen.addToWorkList(element); |
| 34 }); | 56 }); |
| 35 List<js.Parameter> parameters = <js.Parameter>[]; | 57 List<js.Parameter> parameters = <js.Parameter>[]; |
| 36 parameterNames.forEach((element, name) { | 58 parameterNames.forEach((element, name) { |
| 37 parameters.add(new js.Parameter(name)); | 59 parameters.add(new js.Parameter(name)); |
| (...skipping 1835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1873 js.Call value = new js.Call(jsHelper, visitArguments([null, argument])); | 1895 js.Call value = new js.Call(jsHelper, visitArguments([null, argument])); |
| 1874 attachLocation(value, argument); | 1896 attachLocation(value, argument); |
| 1875 pushStatement(new js.Throw(value)); | 1897 pushStatement(new js.Throw(value)); |
| 1876 } | 1898 } |
| 1877 | 1899 |
| 1878 void visitSwitch(HSwitch node) { | 1900 void visitSwitch(HSwitch node) { |
| 1879 // Switches are handled using [visitSwitchInfo]. | 1901 // Switches are handled using [visitSwitchInfo]. |
| 1880 } | 1902 } |
| 1881 | 1903 |
| 1882 void visitStatic(HStatic node) { | 1904 void visitStatic(HStatic node) { |
| 1883 world.registerStaticUse(node.element); | 1905 Element element = node.element; |
| 1884 push(new js.VariableUse(compiler.namer.isolateAccess(node.element))); | 1906 world.registerStaticUse(element); |
| 1907 push(new js.VariableUse(compiler.namer.isolateAccess(element)), node); |
| 1908 } |
| 1909 |
| 1910 void visitLazyStatic(HLazyStatic node) { |
| 1911 Element element = node.element; |
| 1912 world.registerStaticUse(element); |
| 1913 String lazyGetter = compiler.namer.isolateLazyInitializerAccess(element); |
| 1914 js.VariableUse target = new js.VariableUse(lazyGetter); |
| 1915 js.Call call = new js.Call(target, <js.Expression>[]); |
| 1916 push(call, node); |
| 1885 } | 1917 } |
| 1886 | 1918 |
| 1887 void visitStaticStore(HStaticStore node) { | 1919 void visitStaticStore(HStaticStore node) { |
| 1888 world.registerStaticUse(node.element); | 1920 world.registerStaticUse(node.element); |
| 1889 js.VariableUse variableUse = | 1921 js.VariableUse variableUse = |
| 1890 new js.VariableUse(compiler.namer.isolateAccess(node.element)); | 1922 new js.VariableUse(compiler.namer.isolateAccess(node.element)); |
| 1891 use(node.inputs[0]); | 1923 use(node.inputs[0]); |
| 1892 push(new js.Assignment(variableUse, pop()), node); | 1924 push(new js.Assignment(variableUse, pop()), node); |
| 1893 } | 1925 } |
| 1894 | 1926 |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2386 for (; i < maxBailoutParameters; i++) { | 2418 for (; i < maxBailoutParameters; i++) { |
| 2387 arguments.add(new js.LiteralNumber('0')); | 2419 arguments.add(new js.LiteralNumber('0')); |
| 2388 } | 2420 } |
| 2389 | 2421 |
| 2390 js.Expression bailoutTarget; | 2422 js.Expression bailoutTarget; |
| 2391 if (element.isInstanceMember()) { | 2423 if (element.isInstanceMember()) { |
| 2392 // TODO(ngeoffray): This does not work in case we come from a | 2424 // TODO(ngeoffray): This does not work in case we come from a |
| 2393 // super call. We must make bailout names unique. | 2425 // super call. We must make bailout names unique. |
| 2394 String bailoutName = namer.getBailoutName(element); | 2426 String bailoutName = namer.getBailoutName(element); |
| 2395 bailoutTarget = new js.PropertyAccess.field(new js.This(), bailoutName); | 2427 bailoutTarget = new js.PropertyAccess.field(new js.This(), bailoutName); |
| 2428 } else if (element.isField()) { |
| 2429 String bailoutName = namer.isolateLazyInitializerBailoutAccess(element); |
| 2430 bailoutTarget = new js.VariableUse(bailoutName); |
| 2396 } else { | 2431 } else { |
| 2397 bailoutTarget = new js.VariableUse(namer.isolateBailoutAccess(element)); | 2432 bailoutTarget = new js.VariableUse(namer.isolateBailoutAccess(element)); |
| 2398 } | 2433 } |
| 2399 js.Call call = new js.Call(bailoutTarget, arguments); | 2434 js.Call call = new js.Call(bailoutTarget, arguments); |
| 2400 attachLocation(call, guard); | 2435 attachLocation(call, guard); |
| 2401 return new js.Return(call); | 2436 return new js.Return(call); |
| 2402 } | 2437 } |
| 2403 | 2438 |
| 2404 void visitTypeGuard(HTypeGuard node) { | 2439 void visitTypeGuard(HTypeGuard node) { |
| 2405 HInstruction input = node.guarded; | 2440 HInstruction input = node.guarded; |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2847 if (leftType.canBeNull() && rightType.canBeNull()) { | 2882 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 2848 if (left.isConstantNull() || right.isConstantNull() || | 2883 if (left.isConstantNull() || right.isConstantNull() || |
| 2849 (leftType.isPrimitive() && leftType == rightType)) { | 2884 (leftType.isPrimitive() && leftType == rightType)) { |
| 2850 return '=='; | 2885 return '=='; |
| 2851 } | 2886 } |
| 2852 return null; | 2887 return null; |
| 2853 } else { | 2888 } else { |
| 2854 return '==='; | 2889 return '==='; |
| 2855 } | 2890 } |
| 2856 } | 2891 } |
| OLD | NEW |