Mercurial > hg > truffle
annotate src/share/vm/c1/c1_CFGPrinter.cpp @ 8463:b2161263e9f2
Cleanup unit tests : they should not print to stdout/stderr
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Mon, 25 Mar 2013 19:22:03 +0100 |
parents | b9a9ed0f8eeb |
children | 78bbf4d43a14 |
rev | line source |
---|---|
0 | 1 /* |
6842
b9a9ed0f8eeb
7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents:
6197
diff
changeset
|
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_CFGPrinter.hpp" | |
27 #include "c1/c1_IR.hpp" | |
28 #include "c1/c1_InstructionPrinter.hpp" | |
29 #include "c1/c1_LIR.hpp" | |
30 #include "c1/c1_LinearScan.hpp" | |
31 #include "c1/c1_ValueStack.hpp" | |
0 | 32 |
33 #ifndef PRODUCT | |
34 | |
35 | |
6197 | 36 class CFGPrinterOutput : public CHeapObj<mtCompiler> { |
0 | 37 private: |
38 outputStream* _output; | |
39 | |
40 Compilation* _compilation; | |
41 bool _do_print_HIR; | |
42 bool _do_print_LIR; | |
43 | |
44 class PrintBlockClosure: public BlockClosure { | |
45 void block_do(BlockBegin* block) { if (block != NULL) CFGPrinter::output()->print_block(block); } | |
46 }; | |
47 | |
48 | |
49 outputStream* output() { assert(_output != NULL, ""); return _output; } | |
50 | |
51 void inc_indent(); | |
52 void dec_indent(); | |
53 void print(const char* format, ...); | |
54 void print_begin(const char* tag); | |
55 void print_end(const char* tag); | |
56 | |
57 char* method_name(ciMethod* method, bool short_name = false); | |
58 | |
59 public: | |
60 CFGPrinterOutput(); | |
61 | |
62 void set_compilation(Compilation* compilation) { _compilation = compilation; } | |
63 void set_print_flags(bool do_print_HIR, bool do_print_LIR) { _do_print_HIR = do_print_HIR; _do_print_LIR = do_print_LIR; } | |
64 | |
65 void print_compilation(); | |
66 void print_intervals(IntervalList* intervals, const char* name); | |
67 | |
68 void print_state(BlockBegin* block); | |
69 void print_operand(Value instr); | |
70 void print_HIR(Value instr); | |
71 void print_HIR(BlockBegin* block); | |
72 void print_LIR(BlockBegin* block); | |
73 void print_block(BlockBegin* block); | |
74 void print_cfg(BlockList* blocks, const char* name); | |
75 void print_cfg(IR* blocks, const char* name); | |
76 }; | |
77 | |
78 CFGPrinterOutput* CFGPrinter::_output = NULL; | |
79 | |
80 | |
81 | |
82 | |
83 void CFGPrinter::print_compilation(Compilation* compilation) { | |
84 if (_output == NULL) { | |
85 _output = new CFGPrinterOutput(); | |
86 } | |
87 output()->set_compilation(compilation); | |
88 output()->print_compilation(); | |
89 } | |
90 | |
91 void CFGPrinter::print_cfg(BlockList* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) { | |
92 output()->set_print_flags(do_print_HIR, do_print_LIR); | |
93 output()->print_cfg(blocks, name); | |
94 } | |
95 | |
96 void CFGPrinter::print_cfg(IR* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) { | |
97 output()->set_print_flags(do_print_HIR, do_print_LIR); | |
98 output()->print_cfg(blocks, name); | |
99 } | |
100 | |
101 | |
102 void CFGPrinter::print_intervals(IntervalList* intervals, const char* name) { | |
103 output()->print_intervals(intervals, name); | |
104 } | |
105 | |
106 | |
107 | |
108 CFGPrinterOutput::CFGPrinterOutput() | |
6197 | 109 : _output(new(ResourceObj::C_HEAP, mtCompiler) fileStream("output.cfg")) |
0 | 110 { |
111 } | |
112 | |
113 | |
114 | |
115 void CFGPrinterOutput::inc_indent() { | |
116 output()->inc(); | |
117 output()->inc(); | |
118 } | |
119 | |
120 void CFGPrinterOutput::dec_indent() { | |
121 output()->dec(); | |
122 output()->dec(); | |
123 } | |
124 | |
125 void CFGPrinterOutput::print(const char* format, ...) { | |
126 output()->indent(); | |
127 | |
128 va_list ap; | |
129 va_start(ap, format); | |
130 output()->vprint_cr(format, ap); | |
131 va_end(ap); | |
132 } | |
133 | |
134 void CFGPrinterOutput::print_begin(const char* tag) { | |
135 output()->indent(); | |
136 output()->print_cr("begin_%s", tag); | |
137 inc_indent(); | |
138 } | |
139 | |
140 void CFGPrinterOutput::print_end(const char* tag) { | |
141 dec_indent(); | |
142 output()->indent(); | |
143 output()->print_cr("end_%s", tag); | |
144 } | |
145 | |
146 | |
147 char* CFGPrinterOutput::method_name(ciMethod* method, bool short_name) { | |
148 stringStream name; | |
149 if (short_name) { | |
150 method->print_short_name(&name); | |
151 } else { | |
152 method->print_name(&name); | |
153 } | |
154 return name.as_string(); | |
155 | |
156 } | |
157 | |
158 | |
159 void CFGPrinterOutput::print_compilation() { | |
160 print_begin("compilation"); | |
161 | |
162 print("name \"%s\"", method_name(_compilation->method(), true)); | |
163 print("method \"%s\"", method_name(_compilation->method())); | |
164 print("date "INT64_FORMAT, os::javaTimeMillis()); | |
165 | |
166 print_end("compilation"); | |
167 } | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 void CFGPrinterOutput::print_state(BlockBegin* block) { | |
174 print_begin("states"); | |
175 | |
176 InstructionPrinter ip(true, output()); | |
177 | |
178 ValueStack* state = block->state(); | |
179 int index; | |
180 Value value; | |
181 | |
182 for_each_state(state) { | |
183 print_begin("locals"); | |
184 print("size %d", state->locals_size()); | |
185 print("method \"%s\"", method_name(state->scope()->method())); | |
186 | |
187 for_each_local_value(state, index, value) { | |
188 ip.print_phi(index, value, block); | |
189 print_operand(value); | |
190 output()->cr(); | |
191 } | |
192 print_end("locals"); | |
1819 | 193 |
194 if (state->stack_size() > 0) { | |
195 print_begin("stack"); | |
196 print("size %d", state->stack_size()); | |
197 print("method \"%s\"", method_name(state->scope()->method())); | |
198 | |
199 for_each_stack_value(state, index, value) { | |
200 ip.print_phi(index, value, block); | |
201 print_operand(value); | |
202 output()->cr(); | |
203 } | |
204 | |
205 print_end("stack"); | |
206 } | |
207 | |
208 if (state->locks_size() > 0) { | |
209 print_begin("locks"); | |
210 print("size %d", state->locks_size()); | |
211 print("method \"%s\"", method_name(state->scope()->method())); | |
212 | |
213 for_each_lock_value(state, index, value) { | |
214 ip.print_phi(index, value, block); | |
215 print_operand(value); | |
216 output()->cr(); | |
217 } | |
218 print_end("locks"); | |
219 } | |
0 | 220 } |
221 | |
222 print_end("states"); | |
223 } | |
224 | |
225 | |
226 void CFGPrinterOutput::print_operand(Value instr) { | |
227 if (instr->operand()->is_virtual()) { | |
228 output()->print(" \""); | |
229 instr->operand()->print(output()); | |
230 output()->print("\" "); | |
231 } | |
232 } | |
233 | |
234 void CFGPrinterOutput::print_HIR(Value instr) { | |
235 InstructionPrinter ip(true, output()); | |
236 | |
237 if (instr->is_pinned()) { | |
238 output()->put('.'); | |
239 } | |
1819 | 240 |
241 output()->print("%d %d ", instr->printable_bci(), instr->use_count()); | |
0 | 242 |
243 print_operand(instr); | |
244 | |
245 ip.print_temp(instr); | |
246 output()->print(" "); | |
247 ip.print_instr(instr); | |
248 | |
249 output()->print_cr(" <|@"); | |
250 } | |
251 | |
252 void CFGPrinterOutput::print_HIR(BlockBegin* block) { | |
253 print_begin("HIR"); | |
254 | |
255 Value cur = block->next(); | |
256 while (cur != NULL) { | |
257 print_HIR(cur); | |
258 cur = cur->next(); | |
259 } | |
260 | |
261 print_end("HIR"); | |
262 } | |
263 | |
264 void CFGPrinterOutput::print_LIR(BlockBegin* block) { | |
265 print_begin("LIR"); | |
266 | |
267 for (int i = 0; i < block->lir()->length(); i++) { | |
268 block->lir()->at(i)->print_on(output()); | |
269 output()->print_cr(" <|@ "); | |
270 } | |
271 | |
272 print_end("LIR"); | |
273 } | |
274 | |
275 | |
276 void CFGPrinterOutput::print_block(BlockBegin* block) { | |
277 print_begin("block"); | |
278 | |
279 print("name \"B%d\"", block->block_id()); | |
280 | |
281 print("from_bci %d", block->bci()); | |
1819 | 282 print("to_bci %d", (block->end() == NULL ? -1 : block->end()->printable_bci())); |
0 | 283 |
284 output()->indent(); | |
285 output()->print("predecessors "); | |
286 int i; | |
287 for (i = 0; i < block->number_of_preds(); i++) { | |
288 output()->print("\"B%d\" ", block->pred_at(i)->block_id()); | |
289 } | |
290 output()->cr(); | |
291 | |
292 output()->indent(); | |
293 output()->print("successors "); | |
294 for (i = 0; i < block->number_of_sux(); i++) { | |
295 output()->print("\"B%d\" ", block->sux_at(i)->block_id()); | |
296 } | |
297 output()->cr(); | |
298 | |
299 output()->indent(); | |
300 output()->print("xhandlers"); | |
301 for (i = 0; i < block->number_of_exception_handlers(); i++) { | |
302 output()->print("\"B%d\" ", block->exception_handler_at(i)->block_id()); | |
303 } | |
304 output()->cr(); | |
305 | |
306 output()->indent(); | |
307 output()->print("flags "); | |
308 if (block->is_set(BlockBegin::std_entry_flag)) output()->print("\"std\" "); | |
309 if (block->is_set(BlockBegin::osr_entry_flag)) output()->print("\"osr\" "); | |
310 if (block->is_set(BlockBegin::exception_entry_flag)) output()->print("\"ex\" "); | |
311 if (block->is_set(BlockBegin::subroutine_entry_flag)) output()->print("\"sr\" "); | |
312 if (block->is_set(BlockBegin::backward_branch_target_flag)) output()->print("\"bb\" "); | |
313 if (block->is_set(BlockBegin::parser_loop_header_flag)) output()->print("\"plh\" "); | |
314 if (block->is_set(BlockBegin::critical_edge_split_flag)) output()->print("\"ces\" "); | |
315 if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) output()->print("\"llh\" "); | |
316 if (block->is_set(BlockBegin::linear_scan_loop_end_flag)) output()->print("\"lle\" "); | |
317 output()->cr(); | |
318 | |
319 if (block->dominator() != NULL) { | |
320 print("dominator \"B%d\"", block->dominator()->block_id()); | |
321 } | |
322 if (block->loop_index() != -1) { | |
323 print("loop_index %d", block->loop_index()); | |
324 print("loop_depth %d", block->loop_depth()); | |
325 } | |
326 | |
327 if (block->first_lir_instruction_id() != -1) { | |
328 print("first_lir_id %d", block->first_lir_instruction_id()); | |
329 print("last_lir_id %d", block->last_lir_instruction_id()); | |
330 } | |
331 | |
332 if (_do_print_HIR) { | |
333 print_state(block); | |
334 print_HIR(block); | |
335 } | |
336 | |
337 if (_do_print_LIR) { | |
338 print_LIR(block); | |
339 } | |
340 | |
341 print_end("block"); | |
342 } | |
343 | |
344 | |
345 | |
346 void CFGPrinterOutput::print_cfg(BlockList* blocks, const char* name) { | |
347 print_begin("cfg"); | |
348 print("name \"%s\"", name); | |
349 | |
350 PrintBlockClosure print_block; | |
351 blocks->iterate_forward(&print_block); | |
352 | |
353 print_end("cfg"); | |
354 output()->flush(); | |
355 } | |
356 | |
357 void CFGPrinterOutput::print_cfg(IR* blocks, const char* name) { | |
358 print_begin("cfg"); | |
359 print("name \"%s\"", name); | |
360 | |
361 PrintBlockClosure print_block; | |
362 blocks->iterate_preorder(&print_block); | |
363 | |
364 print_end("cfg"); | |
365 output()->flush(); | |
366 } | |
367 | |
368 | |
369 | |
370 | |
371 void CFGPrinterOutput::print_intervals(IntervalList* intervals, const char* name) { | |
372 print_begin("intervals"); | |
373 print("name \"%s\"", name); | |
374 | |
375 for (int i = 0; i < intervals->length(); i++) { | |
376 if (intervals->at(i) != NULL) { | |
377 intervals->at(i)->print(output()); | |
378 } | |
379 } | |
380 | |
381 print_end("intervals"); | |
382 output()->flush(); | |
383 } | |
384 | |
385 | |
386 #endif |