OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/graph-visualizer.h" | 5 #include "src/compiler/graph-visualizer.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 } | 53 } |
54 return false; | 54 return false; |
55 } | 55 } |
56 | 56 |
57 const std::string str_; | 57 const std::string str_; |
58 const char* const escaped_chars_; | 58 const char* const escaped_chars_; |
59 }; | 59 }; |
60 | 60 |
61 class JSONGraphNodeWriter { | 61 class JSONGraphNodeWriter { |
62 public: | 62 public: |
63 JSONGraphNodeWriter(std::ostream& os, Zone* zone, const Graph* graph) | 63 JSONGraphNodeWriter(std::ostream& os, Zone* zone, const Graph* graph, |
64 : os_(os), all_(zone, graph), first_node_(true) {} | 64 const SourcePositionTable* positions) |
| 65 : os_(os), all_(zone, graph), positions_(positions), first_node_(true) {} |
65 | 66 |
66 void Print() { | 67 void Print() { |
67 for (Node* const node : all_.live) PrintNode(node); | 68 for (Node* const node : all_.live) PrintNode(node); |
| 69 os_ << "\n"; |
68 } | 70 } |
69 | 71 |
70 void PrintNode(Node* node) { | 72 void PrintNode(Node* node) { |
71 if (first_node_) { | 73 if (first_node_) { |
72 first_node_ = false; | 74 first_node_ = false; |
73 } else { | 75 } else { |
74 os_ << ","; | 76 os_ << ",\n"; |
75 } | 77 } |
76 std::ostringstream label; | 78 std::ostringstream label; |
77 label << *node->op(); | 79 label << *node->op(); |
78 os_ << "{\"id\":" << SafeId(node) << ",\"label\":\"" << Escaped(label, "\"") | 80 os_ << "{\"id\":" << SafeId(node) << ",\"label\":\"" << Escaped(label, "\"") |
79 << "\""; | 81 << "\""; |
80 IrOpcode::Value opcode = node->opcode(); | 82 IrOpcode::Value opcode = node->opcode(); |
81 if (IrOpcode::IsPhiOpcode(opcode)) { | 83 if (IrOpcode::IsPhiOpcode(opcode)) { |
82 os_ << ",\"rankInputs\":[0," << NodeProperties::FirstControlIndex(node) | 84 os_ << ",\"rankInputs\":[0," << NodeProperties::FirstControlIndex(node) |
83 << "]"; | 85 << "]"; |
84 os_ << ",\"rankWithInput\":[" << NodeProperties::FirstControlIndex(node) | 86 os_ << ",\"rankWithInput\":[" << NodeProperties::FirstControlIndex(node) |
85 << "]"; | 87 << "]"; |
86 } else if (opcode == IrOpcode::kIfTrue || opcode == IrOpcode::kIfFalse || | 88 } else if (opcode == IrOpcode::kIfTrue || opcode == IrOpcode::kIfFalse || |
87 opcode == IrOpcode::kLoop) { | 89 opcode == IrOpcode::kLoop) { |
88 os_ << ",\"rankInputs\":[" << NodeProperties::FirstControlIndex(node) | 90 os_ << ",\"rankInputs\":[" << NodeProperties::FirstControlIndex(node) |
89 << "]"; | 91 << "]"; |
90 } | 92 } |
91 if (opcode == IrOpcode::kBranch) { | 93 if (opcode == IrOpcode::kBranch) { |
92 os_ << ",\"rankInputs\":[0]"; | 94 os_ << ",\"rankInputs\":[0]"; |
93 } | 95 } |
| 96 SourcePosition position = positions_->GetSourcePosition(node); |
| 97 if (!position.IsUnknown()) { |
| 98 DCHECK(!position.IsInvalid()); |
| 99 os_ << ",\"pos\":" << position.raw(); |
| 100 } |
94 os_ << ",\"opcode\":\"" << IrOpcode::Mnemonic(node->opcode()) << "\""; | 101 os_ << ",\"opcode\":\"" << IrOpcode::Mnemonic(node->opcode()) << "\""; |
95 os_ << ",\"control\":" << (NodeProperties::IsControl(node) ? "true" | 102 os_ << ",\"control\":" << (NodeProperties::IsControl(node) ? "true" |
96 : "false"); | 103 : "false"); |
97 os_ << "}"; | 104 os_ << "}"; |
98 } | 105 } |
99 | 106 |
100 private: | 107 private: |
101 std::ostream& os_; | 108 std::ostream& os_; |
102 AllNodes all_; | 109 AllNodes all_; |
| 110 const SourcePositionTable* positions_; |
103 bool first_node_; | 111 bool first_node_; |
104 | 112 |
105 DISALLOW_COPY_AND_ASSIGN(JSONGraphNodeWriter); | 113 DISALLOW_COPY_AND_ASSIGN(JSONGraphNodeWriter); |
106 }; | 114 }; |
107 | 115 |
108 | 116 |
109 class JSONGraphEdgeWriter { | 117 class JSONGraphEdgeWriter { |
110 public: | 118 public: |
111 JSONGraphEdgeWriter(std::ostream& os, Zone* zone, const Graph* graph) | 119 JSONGraphEdgeWriter(std::ostream& os, Zone* zone, const Graph* graph) |
112 : os_(os), all_(zone, graph), first_edge_(true) {} | 120 : os_(os), all_(zone, graph), first_edge_(true) {} |
113 | 121 |
114 void Print() { | 122 void Print() { |
115 for (Node* const node : all_.live) PrintEdges(node); | 123 for (Node* const node : all_.live) PrintEdges(node); |
| 124 os_ << "\n"; |
116 } | 125 } |
117 | 126 |
118 void PrintEdges(Node* node) { | 127 void PrintEdges(Node* node) { |
119 for (int i = 0; i < node->InputCount(); i++) { | 128 for (int i = 0; i < node->InputCount(); i++) { |
120 Node* input = node->InputAt(i); | 129 Node* input = node->InputAt(i); |
121 if (input == NULL) continue; | 130 if (input == NULL) continue; |
122 PrintEdge(node, i, input); | 131 PrintEdge(node, i, input); |
123 } | 132 } |
124 } | 133 } |
125 | 134 |
126 void PrintEdge(Node* from, int index, Node* to) { | 135 void PrintEdge(Node* from, int index, Node* to) { |
127 if (first_edge_) { | 136 if (first_edge_) { |
128 first_edge_ = false; | 137 first_edge_ = false; |
129 } else { | 138 } else { |
130 os_ << ","; | 139 os_ << ",\n"; |
131 } | 140 } |
132 const char* edge_type = NULL; | 141 const char* edge_type = NULL; |
133 if (index < NodeProperties::FirstValueIndex(from)) { | 142 if (index < NodeProperties::FirstValueIndex(from)) { |
134 edge_type = "unknown"; | 143 edge_type = "unknown"; |
135 } else if (index < NodeProperties::FirstContextIndex(from)) { | 144 } else if (index < NodeProperties::FirstContextIndex(from)) { |
136 edge_type = "value"; | 145 edge_type = "value"; |
137 } else if (index < NodeProperties::FirstFrameStateIndex(from)) { | 146 } else if (index < NodeProperties::FirstFrameStateIndex(from)) { |
138 edge_type = "context"; | 147 edge_type = "context"; |
139 } else if (index < NodeProperties::FirstEffectIndex(from)) { | 148 } else if (index < NodeProperties::FirstEffectIndex(from)) { |
140 edge_type = "frame-state"; | 149 edge_type = "frame-state"; |
(...skipping 10 matching lines...) Expand all Loading... |
151 std::ostream& os_; | 160 std::ostream& os_; |
152 AllNodes all_; | 161 AllNodes all_; |
153 bool first_edge_; | 162 bool first_edge_; |
154 | 163 |
155 DISALLOW_COPY_AND_ASSIGN(JSONGraphEdgeWriter); | 164 DISALLOW_COPY_AND_ASSIGN(JSONGraphEdgeWriter); |
156 }; | 165 }; |
157 | 166 |
158 | 167 |
159 std::ostream& operator<<(std::ostream& os, const AsJSON& ad) { | 168 std::ostream& operator<<(std::ostream& os, const AsJSON& ad) { |
160 Zone tmp_zone; | 169 Zone tmp_zone; |
161 os << "{\"nodes\":["; | 170 os << "{\n\"nodes\":["; |
162 JSONGraphNodeWriter(os, &tmp_zone, &ad.graph).Print(); | 171 JSONGraphNodeWriter(os, &tmp_zone, &ad.graph, ad.positions).Print(); |
163 os << "],\"edges\":["; | 172 os << "],\n\"edges\":["; |
164 JSONGraphEdgeWriter(os, &tmp_zone, &ad.graph).Print(); | 173 JSONGraphEdgeWriter(os, &tmp_zone, &ad.graph).Print(); |
165 os << "]}"; | 174 os << "]}"; |
166 return os; | 175 return os; |
167 } | 176 } |
168 | 177 |
169 | 178 |
170 class GraphVisualizer { | 179 class GraphVisualizer { |
171 public: | 180 public: |
172 GraphVisualizer(std::ostream& os, Zone* zone, const Graph* graph) | 181 GraphVisualizer(std::ostream& os, Zone* zone, const Graph* graph) |
173 : all_(zone, graph), os_(os) {} | 182 : all_(zone, graph), os_(os) {} |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 os << "#" << SafeId(i) << ":" << SafeMnemonic(i); | 779 os << "#" << SafeId(i) << ":" << SafeMnemonic(i); |
771 } | 780 } |
772 os << ")" << std::endl; | 781 os << ")" << std::endl; |
773 } | 782 } |
774 } | 783 } |
775 return os; | 784 return os; |
776 } | 785 } |
777 } | 786 } |
778 } | 787 } |
779 } // namespace v8::internal::compiler | 788 } // namespace v8::internal::compiler |
OLD | NEW |