| 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 | 6 |
| 7 final JavaScriptBackend backend; | 7 final JavaScriptBackend backend; |
| 8 | 8 |
| 9 SsaCodeGeneratorTask(JavaScriptBackend backend) | 9 SsaCodeGeneratorTask(JavaScriptBackend backend) |
| 10 : this.backend = backend, | 10 : this.backend = backend, |
| 11 super(backend.compiler); | 11 super(backend.compiler); |
| 12 String get name => 'SSA code generator'; | 12 String get name => 'SSA code generator'; |
| 13 NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter; | 13 NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter; |
| 14 | 14 |
| 15 | 15 |
| 16 js.Fun buildJavaScriptFunction(FunctionElement element, | 16 js.Fun buildJavaScriptFunction(FunctionElement element, |
| 17 List<js.Parameter> parameters, | 17 List<js.Parameter> parameters, |
| 18 js.Block body) { | 18 js.Block body) { |
| 19 FunctionExpression expression = element.cachedNode; | 19 FunctionExpression expression = element.cachedNode; |
| 20 js.Fun result = new js.Fun(parameters, body); | 20 js.Fun result = new js.Fun(parameters, body); |
| 21 result.sourcePosition = expression.getBeginToken(); | 21 result.sourcePosition = expression.getBeginToken(); |
| 22 result.endSourcePosition = expression.getEndToken(); | 22 result.endSourcePosition = expression.getEndToken(); |
| 23 return result; | 23 return result; |
| 24 } | 24 } |
| 25 | 25 |
| 26 CodeBuffer prettyPrint(js.Node node, Element positionElement) { | 26 CodeBuffer prettyPrint(js.Node node, Element positionElement) { |
| 27 return js.prettyPrint(node, compiler, positionElement); | 27 return js.prettyPrint(node, compiler, positionElement); |
| 28 } | 28 } |
| 29 | 29 |
| 30 CodeBuffer generateCode(WorkItem work, HGraph graph) { |
| 31 if (work.element.isField()) { |
| 32 return generateLazyInitializer(work, graph); |
| 33 } else { |
| 34 return generateMethod(work, graph); |
| 35 } |
| 36 } |
| 37 |
| 38 CodeBuffer generateLazyInitializer(work, graph) { |
| 39 return measure(() { |
| 40 compiler.tracer.traceGraph("codegen", graph); |
| 41 List<js.Parameter> parameters = <js.Parameter>[]; |
| 42 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( |
| 43 backend, work, parameters, new Map<Element, String>()); |
| 44 codegen.visitGraph(graph); |
| 45 js.Block body = codegen.body; |
| 46 Element element = work.element; |
| 47 js.Fun fun = new js.Fun(parameters, body); |
| 48 return prettyPrint(fun, element); |
| 49 }); |
| 50 } |
| 51 |
| 30 CodeBuffer generateMethod(WorkItem work, HGraph graph) { | 52 CodeBuffer generateMethod(WorkItem work, HGraph graph) { |
| 31 return measure(() { | 53 return measure(() { |
| 32 JavaScriptItemCompilationContext context = work.compilationContext; | 54 JavaScriptItemCompilationContext context = work.compilationContext; |
| 33 HTypeMap types = context.types; | 55 HTypeMap types = context.types; |
| 34 graph.exit.predecessors.forEach((block) { | 56 graph.exit.predecessors.forEach((block) { |
| 35 assert(block.last is HGoto || block.last is HReturn); | 57 assert(block.last is HGoto || block.last is HReturn); |
| 36 if (block.last is HReturn) { | 58 if (block.last is HReturn) { |
| 37 backend.registerReturnType(work.element, types[block.last.inputs[0]]); | 59 backend.registerReturnType(work.element, types[block.last.inputs[0]]); |
| 38 } else { | 60 } else { |
| 39 backend.registerReturnType(work.element, HType.NULL); | 61 backend.registerReturnType(work.element, HType.NULL); |
| (...skipping 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1957 backend.registerNonCallStaticUse(node); | 1979 backend.registerNonCallStaticUse(node); |
| 1958 break; | 1980 break; |
| 1959 } | 1981 } |
| 1960 } | 1982 } |
| 1961 } | 1983 } |
| 1962 }); | 1984 }); |
| 1963 world.registerStaticUse(node.element); | 1985 world.registerStaticUse(node.element); |
| 1964 push(new js.VariableUse(compiler.namer.isolateAccess(node.element))); | 1986 push(new js.VariableUse(compiler.namer.isolateAccess(node.element))); |
| 1965 } | 1987 } |
| 1966 | 1988 |
| 1989 void visitLazyStatic(HLazyStatic node) { |
| 1990 Element element = node.element; |
| 1991 world.registerStaticUse(element); |
| 1992 String lazyGetter = compiler.namer.isolateLazyInitializerAccess(element); |
| 1993 js.VariableUse target = new js.VariableUse(lazyGetter); |
| 1994 js.Call call = new js.Call(target, <js.Expression>[]); |
| 1995 push(call, node); |
| 1996 } |
| 1997 |
| 1967 void visitStaticStore(HStaticStore node) { | 1998 void visitStaticStore(HStaticStore node) { |
| 1968 world.registerStaticUse(node.element); | 1999 world.registerStaticUse(node.element); |
| 1969 js.VariableUse variableUse = | 2000 js.VariableUse variableUse = |
| 1970 new js.VariableUse(compiler.namer.isolateAccess(node.element)); | 2001 new js.VariableUse(compiler.namer.isolateAccess(node.element)); |
| 1971 use(node.inputs[0]); | 2002 use(node.inputs[0]); |
| 1972 push(new js.Assignment(variableUse, pop()), node); | 2003 push(new js.Assignment(variableUse, pop()), node); |
| 1973 } | 2004 } |
| 1974 | 2005 |
| 1975 void visitStringConcat(HStringConcat node) { | 2006 void visitStringConcat(HStringConcat node) { |
| 1976 if (isEmptyString(node.left)) { | 2007 if (isEmptyString(node.left)) { |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2431 arguments.add(new js.LiteralNumber('0')); | 2462 arguments.add(new js.LiteralNumber('0')); |
| 2432 } | 2463 } |
| 2433 | 2464 |
| 2434 js.Expression bailoutTarget; | 2465 js.Expression bailoutTarget; |
| 2435 if (element.isInstanceMember()) { | 2466 if (element.isInstanceMember()) { |
| 2436 // TODO(ngeoffray): This does not work in case we come from a | 2467 // TODO(ngeoffray): This does not work in case we come from a |
| 2437 // super call. We must make bailout names unique. | 2468 // super call. We must make bailout names unique. |
| 2438 String bailoutName = namer.getBailoutName(element); | 2469 String bailoutName = namer.getBailoutName(element); |
| 2439 bailoutTarget = new js.PropertyAccess.field(new js.This(), bailoutName); | 2470 bailoutTarget = new js.PropertyAccess.field(new js.This(), bailoutName); |
| 2440 } else { | 2471 } else { |
| 2472 assert(!element.isField()); |
| 2441 bailoutTarget = new js.VariableUse(namer.isolateBailoutAccess(element)); | 2473 bailoutTarget = new js.VariableUse(namer.isolateBailoutAccess(element)); |
| 2442 } | 2474 } |
| 2443 js.Call call = new js.Call(bailoutTarget, arguments); | 2475 js.Call call = new js.Call(bailoutTarget, arguments); |
| 2444 attachLocation(call, guard); | 2476 attachLocation(call, guard); |
| 2445 return new js.Return(call); | 2477 return new js.Return(call); |
| 2446 } | 2478 } |
| 2447 | 2479 |
| 2448 void visitTypeGuard(HTypeGuard node) { | 2480 void visitTypeGuard(HTypeGuard node) { |
| 2449 HInstruction input = node.guarded; | 2481 HInstruction input = node.guarded; |
| 2450 Element indexingBehavior = compiler.jsIndexingBehaviorInterface; | 2482 Element indexingBehavior = compiler.jsIndexingBehaviorInterface; |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2892 if (leftType.canBeNull() && rightType.canBeNull()) { | 2924 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 2893 if (left.isConstantNull() || right.isConstantNull() || | 2925 if (left.isConstantNull() || right.isConstantNull() || |
| 2894 (leftType.isPrimitive() && leftType == rightType)) { | 2926 (leftType.isPrimitive() && leftType == rightType)) { |
| 2895 return '=='; | 2927 return '=='; |
| 2896 } | 2928 } |
| 2897 return null; | 2929 return null; |
| 2898 } else { | 2930 } else { |
| 2899 return '==='; | 2931 return '==='; |
| 2900 } | 2932 } |
| 2901 } | 2933 } |
| OLD | NEW |