| 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 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); | 6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); |
| 7 String get name() => 'SSA code generator'; | 7 String get name() => 'SSA code generator'; |
| 8 | 8 |
| 9 String generate(WorkItem work, HGraph graph) { | 9 String generate(WorkItem work, HGraph graph) { |
| 10 return measure(() { | 10 return measure(() { |
| 11 FunctionElement function = work.element; | 11 FunctionElement function = work.element; |
| 12 Map<Element, String> parameterNames = | 12 Map<Element, String> parameterNames = |
| 13 new LinkedHashMap<Element, String>(); | 13 new LinkedHashMap<Element, String>(); |
| 14 | 14 |
| 15 function.computeParameters(compiler).forEachParameter((Element element) { | 15 function.computeParameters(compiler).forEachParameter((Element element) { |
| 16 parameterNames[element] = JsNames.getValid('${element.name}'); | 16 parameterNames[element] = |
| 17 JsNames.getValid('${element.name.slowToString()}'); |
| 17 }); | 18 }); |
| 18 | 19 |
| 19 String code = generateMethod(parameterNames, work, graph); | 20 String code = generateMethod(parameterNames, work, graph); |
| 20 return code; | 21 return code; |
| 21 }); | 22 }); |
| 22 } | 23 } |
| 23 | 24 |
| 24 void preGenerateMethod(HGraph graph, WorkItem work) { | 25 void preGenerateMethod(HGraph graph, WorkItem work) { |
| 25 if (GENERATE_SSA_TRACE) { | 26 if (GENERATE_SSA_TRACE) { |
| 26 new HTracer.singleton().traceGraph("codegen", graph); | 27 new HTracer.singleton().traceGraph("codegen", graph); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 Element element = local.element; | 169 Element element = local.element; |
| 169 if (element != null && element.kind == ElementKind.PARAMETER) { | 170 if (element != null && element.kind == ElementKind.PARAMETER) { |
| 170 return parameterNames[element]; | 171 return parameterNames[element]; |
| 171 } | 172 } |
| 172 int id = local.id; | 173 int id = local.id; |
| 173 String name = names[id]; | 174 String name = names[id]; |
| 174 if (name !== null) return name; | 175 if (name !== null) return name; |
| 175 | 176 |
| 176 String prefix; | 177 String prefix; |
| 177 if (element !== null) { | 178 if (element !== null) { |
| 178 prefix = element.name.stringValue; | 179 prefix = element.name.slowToString(); |
| 179 } else { | 180 } else { |
| 180 prefix = 'v'; | 181 prefix = 'v'; |
| 181 } | 182 } |
| 182 if (!prefixes.containsKey(prefix)) { | 183 if (!prefixes.containsKey(prefix)) { |
| 183 prefixes[prefix] = 0; | 184 prefixes[prefix] = 0; |
| 184 return newName(id, prefix); | 185 return newName(id, prefix); |
| 185 } else { | 186 } else { |
| 186 return newName(id, '${prefix}_${prefixes[prefix]++}'); | 187 return newName(id, '${prefix}_${prefixes[prefix]++}'); |
| 187 } | 188 } |
| 188 } | 189 } |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 unreachable(); | 401 unreachable(); |
| 401 } | 402 } |
| 402 assert(dominated[0] == currentBlock.successors[0]); | 403 assert(dominated[0] == currentBlock.successors[0]); |
| 403 visitBasicBlock(dominated[0]); | 404 visitBasicBlock(dominated[0]); |
| 404 } | 405 } |
| 405 | 406 |
| 406 // Used to write the name of labels. | 407 // Used to write the name of labels. |
| 407 // The default implementation uses the unmodified Dart label name. | 408 // The default implementation uses the unmodified Dart label name. |
| 408 // Specializations might change this. | 409 // Specializations might change this. |
| 409 void addLabel(SourceString label) { | 410 void addLabel(SourceString label) { |
| 410 buffer.add(label.toString()); | 411 buffer.add(label.slowToString()); |
| 411 } | 412 } |
| 412 | 413 |
| 413 visitBreak(HBreak node) { | 414 visitBreak(HBreak node) { |
| 414 assert(currentBlock.successors.length == 1); | 415 assert(currentBlock.successors.length == 1); |
| 415 // No block finishing with a 'break' can have more than | 416 // No block finishing with a 'break' can have more than |
| 416 // one dominated block (since it has only one successor). | 417 // one dominated block (since it has only one successor). |
| 417 // If the successor is dominated by another block, then the other block | 418 // If the successor is dominated by another block, then the other block |
| 418 // is responsible for visiting the successor. | 419 // is responsible for visiting the successor. |
| 419 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; | 420 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; |
| 420 assert(dominated.isEmpty()); | 421 assert(dominated.isEmpty()); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 String className = compiler.namer.isolatePropertyAccess(superClass); | 559 String className = compiler.namer.isolatePropertyAccess(superClass); |
| 559 String methodName = compiler.namer.instanceMethodName( | 560 String methodName = compiler.namer.instanceMethodName( |
| 560 superMethod.name, argumentCount); | 561 superMethod.name, argumentCount); |
| 561 buffer.add('$className.prototype.$methodName.call'); | 562 buffer.add('$className.prototype.$methodName.call'); |
| 562 visitArguments(node.inputs); | 563 visitArguments(node.inputs); |
| 563 endExpression(JSPrecedence.CALL_PRECEDENCE); | 564 endExpression(JSPrecedence.CALL_PRECEDENCE); |
| 564 compiler.registerStaticUse(superMethod); | 565 compiler.registerStaticUse(superMethod); |
| 565 } | 566 } |
| 566 | 567 |
| 567 visitFieldGet(HFieldGet node) { | 568 visitFieldGet(HFieldGet node) { |
| 568 String name = JsNames.getValid('${node.element.name}'); | 569 String name = JsNames.getValid(node.element.name.slowToString()); |
| 569 if (node.receiver !== null) { | 570 if (node.receiver !== null) { |
| 570 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); | 571 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); |
| 571 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); | 572 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); |
| 572 buffer.add('.'); | 573 buffer.add('.'); |
| 573 buffer.add(name); | 574 buffer.add(name); |
| 574 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); | 575 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); |
| 575 } else { | 576 } else { |
| 576 buffer.add(name); | 577 buffer.add(name); |
| 577 } | 578 } |
| 578 } | 579 } |
| 579 | 580 |
| 580 visitFieldSet(HFieldSet node) { | 581 visitFieldSet(HFieldSet node) { |
| 581 if (node.receiver !== null) { | 582 if (node.receiver !== null) { |
| 582 beginExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); | 583 beginExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); |
| 583 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); | 584 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); |
| 584 buffer.add('.'); | 585 buffer.add('.'); |
| 585 } else { | 586 } else { |
| 586 // TODO(ngeoffray): Remove the 'var' once we don't globally box | 587 // TODO(ngeoffray): Remove the 'var' once we don't globally box |
| 587 // variables used in a try/catch. | 588 // variables used in a try/catch. |
| 588 buffer.add('var '); | 589 buffer.add('var '); |
| 589 } | 590 } |
| 590 String name = JsNames.getValid('${node.element.name}'); | 591 String name = JsNames.getValid(node.element.name.slowToString()); |
| 591 buffer.add(name); | 592 buffer.add(name); |
| 592 buffer.add(' = '); | 593 buffer.add(' = '); |
| 593 use(node.value, JSPrecedence.ASSIGNMENT_PRECEDENCE); | 594 use(node.value, JSPrecedence.ASSIGNMENT_PRECEDENCE); |
| 594 if (node.receiver !== null) { | 595 if (node.receiver !== null) { |
| 595 endExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); | 596 endExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); |
| 596 } | 597 } |
| 597 } | 598 } |
| 598 | 599 |
| 599 visitForeign(HForeign node) { | 600 visitForeign(HForeign node) { |
| 600 String code = '${node.code}'; | 601 String code = '${node.code}'; |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 buffer.add(')) '); | 1059 buffer.add(')) '); |
| 1059 bailout(node, 'Not a string or array'); | 1060 bailout(node, 'Not a string or array'); |
| 1060 } else { | 1061 } else { |
| 1061 unreachable(); | 1062 unreachable(); |
| 1062 } | 1063 } |
| 1063 } | 1064 } |
| 1064 | 1065 |
| 1065 void beginLoop(HBasicBlock block) { | 1066 void beginLoop(HBasicBlock block) { |
| 1066 addIndentation(); | 1067 addIndentation(); |
| 1067 for (SourceString label in block.loopInformation.labels) { | 1068 for (SourceString label in block.loopInformation.labels) { |
| 1068 buffer.add("${label.stringValue}:"); | 1069 buffer.add("${label.slowToString()}:"); |
| 1069 } | 1070 } |
| 1070 buffer.add('while (true) {\n'); | 1071 buffer.add('while (true) {\n'); |
| 1071 indent++; | 1072 indent++; |
| 1072 } | 1073 } |
| 1073 | 1074 |
| 1074 void endLoop(HBasicBlock block) { | 1075 void endLoop(HBasicBlock block) { |
| 1075 indent--; | 1076 indent--; |
| 1076 addIndentation(); | 1077 addIndentation(); |
| 1077 buffer.add('}\n'); // Close 'while' loop. | 1078 buffer.add('}\n'); // Close 'while' loop. |
| 1078 } | 1079 } |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 startBailoutSwitch(); | 1330 startBailoutSwitch(); |
| 1330 } | 1331 } |
| 1331 } | 1332 } |
| 1332 | 1333 |
| 1333 void endElse(HIf node) { | 1334 void endElse(HIf node) { |
| 1334 if (node.elseBlock.hasBailouts()) { | 1335 if (node.elseBlock.hasBailouts()) { |
| 1335 endBailoutSwitch(); | 1336 endBailoutSwitch(); |
| 1336 } | 1337 } |
| 1337 } | 1338 } |
| 1338 } | 1339 } |
| OLD | NEW |