| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library dart_backend.tracer; | 5 library dart_backend.tracer; |
| 6 | 6 |
| 7 import 'dart:async' show EventSink; | 7 import 'dart:async' show EventSink; |
| 8 import '../tracer.dart'; | 8 import '../tracer.dart'; |
| 9 import 'dart_tree.dart'; | 9 import 'dart_tree.dart'; |
| 10 | 10 |
| 11 class Block { | 11 class Block { |
| 12 Label label; |
| 12 int index; | 13 int index; |
| 13 final List<Statement> statements = <Statement>[]; | 14 final List<Statement> statements = <Statement>[]; |
| 14 final List<Block> predecessors = <Block>[]; | 15 final List<Block> predecessors = <Block>[]; |
| 15 final List<Block> successors = <Block>[]; | 16 final List<Block> successors = <Block>[]; |
| 16 | 17 |
| 17 String get name => 'B$index'; | 18 String get name => 'B$index'; |
| 18 | 19 |
| 20 Block([this.label]); |
| 21 |
| 19 void addEdgeTo(Block successor) { | 22 void addEdgeTo(Block successor) { |
| 20 successors.add(successor); | 23 successors.add(successor); |
| 21 successor.predecessors.add(this); | 24 successor.predecessors.add(this); |
| 22 } | 25 } |
| 23 } | 26 } |
| 24 | 27 |
| 25 class BlockCollector extends Visitor { | 28 class BlockCollector extends Visitor { |
| 26 // Accumulate a list of blocks. The current block is the last block in | 29 // Accumulate a list of blocks. The current block is the last block in |
| 27 // the list. | 30 // the list. |
| 28 final List<Block> blocks = [new Block()..index = 0]; | 31 final List<Block> blocks = [new Block()..index = 0]; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 53 visitConcatenateStrings(ConcatenateStrings node) {} | 56 visitConcatenateStrings(ConcatenateStrings node) {} |
| 54 visitLiteralList(LiteralList node) {} | 57 visitLiteralList(LiteralList node) {} |
| 55 visitLiteralMap(LiteralMap node) {} | 58 visitLiteralMap(LiteralMap node) {} |
| 56 visitInvokeConstConstructor(InvokeConstConstructor node) {} | 59 visitInvokeConstConstructor(InvokeConstConstructor node) {} |
| 57 visitConstant(Constant node) {} | 60 visitConstant(Constant node) {} |
| 58 visitConditional(Conditional node) {} | 61 visitConditional(Conditional node) {} |
| 59 visitLogicalOperator(LogicalOperator node) {} | 62 visitLogicalOperator(LogicalOperator node) {} |
| 60 visitNot(Not node) {} | 63 visitNot(Not node) {} |
| 61 | 64 |
| 62 visitLabeledStatement(LabeledStatement node) { | 65 visitLabeledStatement(LabeledStatement node) { |
| 63 Block target = new Block(); | 66 Block target = new Block(node.label); |
| 64 breakTargets[node.label] = target; | 67 breakTargets[node.label] = target; |
| 65 visitStatement(node.body); | 68 visitStatement(node.body); |
| 66 _addBlock(target); | 69 _addBlock(target); |
| 67 visitStatement(node.next); | 70 visitStatement(node.next); |
| 68 } | 71 } |
| 69 | 72 |
| 70 visitAssign(Assign node) { | 73 visitAssign(Assign node) { |
| 71 _addStatement(node); | 74 _addStatement(node); |
| 72 visitStatement(node.next); | 75 visitStatement(node.next); |
| 73 } | 76 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 printProperty("successors", block.successors.map((b) => b.name)); | 149 printProperty("successors", block.successors.map((b) => b.name)); |
| 147 printEmptyProperty("xhandlers"); | 150 printEmptyProperty("xhandlers"); |
| 148 printEmptyProperty("flags"); | 151 printEmptyProperty("flags"); |
| 149 tag("states", () { | 152 tag("states", () { |
| 150 tag("locals", () { | 153 tag("locals", () { |
| 151 printProperty("size", 0); | 154 printProperty("size", 0); |
| 152 printProperty("method", "None"); | 155 printProperty("method", "None"); |
| 153 }); | 156 }); |
| 154 }); | 157 }); |
| 155 tag("HIR", () { | 158 tag("HIR", () { |
| 159 if (block.label != null) { |
| 160 printStatement(null, |
| 161 "Label ${block.name}, breakCount=${block.label.breakCount}"); |
| 162 } |
| 156 block.statements.forEach(visitStatement); | 163 block.statements.forEach(visitStatement); |
| 157 }); | 164 }); |
| 158 }); | 165 }); |
| 159 } | 166 } |
| 160 | 167 |
| 161 void printStatement(String name, String contents) { | 168 void printStatement(String name, String contents) { |
| 162 int bci = 0; | 169 int bci = 0; |
| 163 int uses = 0; | 170 int uses = 0; |
| 164 if (name == null) { | 171 if (name == null) { |
| 165 name = 'x${statementCounter++}'; | 172 name = 'x${statementCounter++}'; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 180 printStatement(null, "dead-use ${node.value}"); | 187 printStatement(null, "dead-use ${node.value}"); |
| 181 } | 188 } |
| 182 | 189 |
| 183 visitLabeledStatement(LabeledStatement node) { | 190 visitLabeledStatement(LabeledStatement node) { |
| 184 // These do not get added to a block's list of statements. | 191 // These do not get added to a block's list of statements. |
| 185 } | 192 } |
| 186 | 193 |
| 187 visitAssign(Assign node) { | 194 visitAssign(Assign node) { |
| 188 String name = names.varName(node.variable); | 195 String name = names.varName(node.variable); |
| 189 String rhs = expr(node.definition); | 196 String rhs = expr(node.definition); |
| 190 printStatement(name, "let $name = $rhs"); | 197 String extra = node.hasExactlyOneUse ? "[single-use]" : ""; |
| 198 printStatement(null, "assign $name = $rhs $extra"); |
| 191 } | 199 } |
| 192 | 200 |
| 193 visitInvokeMethod(InvokeMethod node) { | 201 visitInvokeMethod(InvokeMethod node) { |
| 194 printStatement(null, expr(node)); | 202 printStatement(null, expr(node)); |
| 195 } | 203 } |
| 196 | 204 |
| 197 visitInvokeConstructor(InvokeConstructor node) { | 205 visitInvokeConstructor(InvokeConstructor node) { |
| 198 printStatement(null, expr(node)); | 206 printStatement(null, expr(node)); |
| 199 } | 207 } |
| 200 | 208 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 229 visitReturn(Return node) { | 237 visitReturn(Return node) { |
| 230 printStatement(null, "return ${expr(node.value)}"); | 238 printStatement(null, "return ${expr(node.value)}"); |
| 231 } | 239 } |
| 232 | 240 |
| 233 visitBreak(Break node) { | 241 visitBreak(Break node) { |
| 234 printStatement(null, "break ${collector.breakTargets[node.target].name}"); | 242 printStatement(null, "break ${collector.breakTargets[node.target].name}"); |
| 235 } | 243 } |
| 236 | 244 |
| 237 visitContinue(Continue node) { | 245 visitContinue(Continue node) { |
| 238 printStatement(null, | 246 printStatement(null, |
| 239 "continue ${collector.breakTargets[node.target].name}"); | 247 "continue ${collector.continueTargets[node.target].name}"); |
| 240 } | 248 } |
| 241 | 249 |
| 242 visitIf(If node) { | 250 visitIf(If node) { |
| 243 String condition = expr(node.condition); | 251 String condition = expr(node.condition); |
| 244 String thenTarget = collector.ifTargets[node.thenStatement].name; | 252 String thenTarget = collector.ifTargets[node.thenStatement].name; |
| 245 String elseTarget = collector.ifTargets[node.elseStatement].name; | 253 String elseTarget = collector.ifTargets[node.elseStatement].name; |
| 246 printStatement(null, "if $condition then $thenTarget else $elseTarget"); | 254 printStatement(null, "if $condition then $thenTarget else $elseTarget"); |
| 247 } | 255 } |
| 248 | 256 |
| 249 visitWhile(While node) { | 257 visitWhile(While node) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 * name to avoid clashing with a previously synthesized variable name. | 405 * name to avoid clashing with a previously synthesized variable name. |
| 398 */ | 406 */ |
| 399 class Names { | 407 class Names { |
| 400 final Map<Variable, String> _names = {}; | 408 final Map<Variable, String> _names = {}; |
| 401 final Set<String> _usedNames = new Set(); | 409 final Set<String> _usedNames = new Set(); |
| 402 int _counter = 0; | 410 int _counter = 0; |
| 403 | 411 |
| 404 String varName(Variable v) { | 412 String varName(Variable v) { |
| 405 String name = _names[v]; | 413 String name = _names[v]; |
| 406 if (name == null) { | 414 if (name == null) { |
| 407 name = v.name; | 415 String prefix = v.element == null ? 'v' : '${v.element.name}_'; |
| 408 if (v.cachedName != null) { | |
| 409 name = v.cachedName; | |
| 410 } | |
| 411 while (name == null || _usedNames.contains(name)) { | 416 while (name == null || _usedNames.contains(name)) { |
| 412 name = "v${_counter++}"; | 417 name = "$prefix${_counter++}"; |
| 413 } | 418 } |
| 414 _names[v] = name; | 419 _names[v] = name; |
| 415 _usedNames.add(name); | 420 _usedNames.add(name); |
| 416 } | 421 } |
| 417 return name; | 422 return name; |
| 418 } | 423 } |
| 419 } | 424 } |
| OLD | NEW |