Mercurial > hg > graal-compiler
annotate src/share/vm/c1/c1_CFGPrinter.cpp @ 1751:2528b5bd749c
6980262: Memory leak when exception is thrown in static initializer
Summary: Use resource memory instead of c-heap for the exception message
Reviewed-by: phh, jmasa
author | kamg |
---|---|
date | Fri, 27 Aug 2010 15:05:28 -0400 |
parents | c18cbe5936b8 |
children | f02a8bbe6ed4 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2005, 2006, 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 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_c1_CFGPrinter.cpp.incl" | |
27 | |
28 #ifndef PRODUCT | |
29 | |
30 | |
31 class CFGPrinterOutput : public CHeapObj { | |
32 private: | |
33 outputStream* _output; | |
34 | |
35 Compilation* _compilation; | |
36 bool _do_print_HIR; | |
37 bool _do_print_LIR; | |
38 | |
39 class PrintBlockClosure: public BlockClosure { | |
40 void block_do(BlockBegin* block) { if (block != NULL) CFGPrinter::output()->print_block(block); } | |
41 }; | |
42 | |
43 | |
44 outputStream* output() { assert(_output != NULL, ""); return _output; } | |
45 | |
46 void inc_indent(); | |
47 void dec_indent(); | |
48 void print(const char* format, ...); | |
49 void print_begin(const char* tag); | |
50 void print_end(const char* tag); | |
51 | |
52 char* method_name(ciMethod* method, bool short_name = false); | |
53 | |
54 public: | |
55 CFGPrinterOutput(); | |
56 | |
57 void set_compilation(Compilation* compilation) { _compilation = compilation; } | |
58 void set_print_flags(bool do_print_HIR, bool do_print_LIR) { _do_print_HIR = do_print_HIR; _do_print_LIR = do_print_LIR; } | |
59 | |
60 void print_compilation(); | |
61 void print_intervals(IntervalList* intervals, const char* name); | |
62 | |
63 void print_state(BlockBegin* block); | |
64 void print_operand(Value instr); | |
65 void print_HIR(Value instr); | |
66 void print_HIR(BlockBegin* block); | |
67 void print_LIR(BlockBegin* block); | |
68 void print_block(BlockBegin* block); | |
69 void print_cfg(BlockList* blocks, const char* name); | |
70 void print_cfg(IR* blocks, const char* name); | |
71 }; | |
72 | |
73 CFGPrinterOutput* CFGPrinter::_output = NULL; | |
74 | |
75 | |
76 | |
77 | |
78 void CFGPrinter::print_compilation(Compilation* compilation) { | |
79 if (_output == NULL) { | |
80 _output = new CFGPrinterOutput(); | |
81 } | |
82 output()->set_compilation(compilation); | |
83 output()->print_compilation(); | |
84 } | |
85 | |
86 void CFGPrinter::print_cfg(BlockList* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) { | |
87 output()->set_print_flags(do_print_HIR, do_print_LIR); | |
88 output()->print_cfg(blocks, name); | |
89 } | |
90 | |
91 void CFGPrinter::print_cfg(IR* 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 | |
97 void CFGPrinter::print_intervals(IntervalList* intervals, const char* name) { | |
98 output()->print_intervals(intervals, name); | |
99 } | |
100 | |
101 | |
102 | |
103 CFGPrinterOutput::CFGPrinterOutput() | |
104 : _output(new(ResourceObj::C_HEAP) fileStream("output.cfg")) | |
105 { | |
106 } | |
107 | |
108 | |
109 | |
110 void CFGPrinterOutput::inc_indent() { | |
111 output()->inc(); | |
112 output()->inc(); | |
113 } | |
114 | |
115 void CFGPrinterOutput::dec_indent() { | |
116 output()->dec(); | |
117 output()->dec(); | |
118 } | |
119 | |
120 void CFGPrinterOutput::print(const char* format, ...) { | |
121 output()->indent(); | |
122 | |
123 va_list ap; | |
124 va_start(ap, format); | |
125 output()->vprint_cr(format, ap); | |
126 va_end(ap); | |
127 } | |
128 | |
129 void CFGPrinterOutput::print_begin(const char* tag) { | |
130 output()->indent(); | |
131 output()->print_cr("begin_%s", tag); | |
132 inc_indent(); | |
133 } | |
134 | |
135 void CFGPrinterOutput::print_end(const char* tag) { | |
136 dec_indent(); | |
137 output()->indent(); | |
138 output()->print_cr("end_%s", tag); | |
139 } | |
140 | |
141 | |
142 char* CFGPrinterOutput::method_name(ciMethod* method, bool short_name) { | |
143 stringStream name; | |
144 if (short_name) { | |
145 method->print_short_name(&name); | |
146 } else { | |
147 method->print_name(&name); | |
148 } | |
149 return name.as_string(); | |
150 | |
151 } | |
152 | |
153 | |
154 void CFGPrinterOutput::print_compilation() { | |
155 print_begin("compilation"); | |
156 | |
157 print("name \"%s\"", method_name(_compilation->method(), true)); | |
158 print("method \"%s\"", method_name(_compilation->method())); | |
159 print("date "INT64_FORMAT, os::javaTimeMillis()); | |
160 | |
161 print_end("compilation"); | |
162 } | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 void CFGPrinterOutput::print_state(BlockBegin* block) { | |
169 print_begin("states"); | |
170 | |
171 InstructionPrinter ip(true, output()); | |
172 | |
173 ValueStack* state = block->state(); | |
174 int index; | |
175 Value value; | |
176 | |
177 if (state->stack_size() > 0) { | |
178 print_begin("stack"); | |
179 print("size %d", state->stack_size()); | |
180 | |
181 for_each_stack_value(state, index, value) { | |
182 ip.print_phi(index, value, block); | |
183 print_operand(value); | |
184 output()->cr(); | |
185 } | |
186 | |
187 print_end("stack"); | |
188 } | |
189 | |
190 if (state->locks_size() > 0) { | |
191 print_begin("locks"); | |
192 print("size %d", state->locks_size()); | |
193 | |
194 for_each_lock_value(state, index, value) { | |
195 ip.print_phi(index, value, block); | |
196 print_operand(value); | |
197 output()->cr(); | |
198 } | |
199 print_end("locks"); | |
200 } | |
201 | |
202 for_each_state(state) { | |
203 print_begin("locals"); | |
204 print("size %d", state->locals_size()); | |
205 print("method \"%s\"", method_name(state->scope()->method())); | |
206 | |
207 for_each_local_value(state, index, value) { | |
208 ip.print_phi(index, value, block); | |
209 print_operand(value); | |
210 output()->cr(); | |
211 } | |
212 print_end("locals"); | |
213 } | |
214 | |
215 print_end("states"); | |
216 } | |
217 | |
218 | |
219 void CFGPrinterOutput::print_operand(Value instr) { | |
220 if (instr->operand()->is_virtual()) { | |
221 output()->print(" \""); | |
222 instr->operand()->print(output()); | |
223 output()->print("\" "); | |
224 } | |
225 } | |
226 | |
227 void CFGPrinterOutput::print_HIR(Value instr) { | |
228 InstructionPrinter ip(true, output()); | |
229 | |
230 if (instr->is_pinned()) { | |
231 output()->put('.'); | |
232 } | |
233 output()->print("%d %d ", instr->bci(), instr->use_count()); | |
234 | |
235 print_operand(instr); | |
236 | |
237 ip.print_temp(instr); | |
238 output()->print(" "); | |
239 ip.print_instr(instr); | |
240 | |
241 output()->print_cr(" <|@"); | |
242 } | |
243 | |
244 void CFGPrinterOutput::print_HIR(BlockBegin* block) { | |
245 print_begin("HIR"); | |
246 | |
247 Value cur = block->next(); | |
248 while (cur != NULL) { | |
249 print_HIR(cur); | |
250 cur = cur->next(); | |
251 } | |
252 | |
253 print_end("HIR"); | |
254 } | |
255 | |
256 void CFGPrinterOutput::print_LIR(BlockBegin* block) { | |
257 print_begin("LIR"); | |
258 | |
259 for (int i = 0; i < block->lir()->length(); i++) { | |
260 block->lir()->at(i)->print_on(output()); | |
261 output()->print_cr(" <|@ "); | |
262 } | |
263 | |
264 print_end("LIR"); | |
265 } | |
266 | |
267 | |
268 void CFGPrinterOutput::print_block(BlockBegin* block) { | |
269 print_begin("block"); | |
270 | |
271 print("name \"B%d\"", block->block_id()); | |
272 | |
273 print("from_bci %d", block->bci()); | |
274 print("to_bci %d", (block->end() == NULL ? -1 : block->end()->bci())); | |
275 | |
276 output()->indent(); | |
277 output()->print("predecessors "); | |
278 int i; | |
279 for (i = 0; i < block->number_of_preds(); i++) { | |
280 output()->print("\"B%d\" ", block->pred_at(i)->block_id()); | |
281 } | |
282 output()->cr(); | |
283 | |
284 output()->indent(); | |
285 output()->print("successors "); | |
286 for (i = 0; i < block->number_of_sux(); i++) { | |
287 output()->print("\"B%d\" ", block->sux_at(i)->block_id()); | |
288 } | |
289 output()->cr(); | |
290 | |
291 output()->indent(); | |
292 output()->print("xhandlers"); | |
293 for (i = 0; i < block->number_of_exception_handlers(); i++) { | |
294 output()->print("\"B%d\" ", block->exception_handler_at(i)->block_id()); | |
295 } | |
296 output()->cr(); | |
297 | |
298 output()->indent(); | |
299 output()->print("flags "); | |
300 if (block->is_set(BlockBegin::std_entry_flag)) output()->print("\"std\" "); | |
301 if (block->is_set(BlockBegin::osr_entry_flag)) output()->print("\"osr\" "); | |
302 if (block->is_set(BlockBegin::exception_entry_flag)) output()->print("\"ex\" "); | |
303 if (block->is_set(BlockBegin::subroutine_entry_flag)) output()->print("\"sr\" "); | |
304 if (block->is_set(BlockBegin::backward_branch_target_flag)) output()->print("\"bb\" "); | |
305 if (block->is_set(BlockBegin::parser_loop_header_flag)) output()->print("\"plh\" "); | |
306 if (block->is_set(BlockBegin::critical_edge_split_flag)) output()->print("\"ces\" "); | |
307 if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) output()->print("\"llh\" "); | |
308 if (block->is_set(BlockBegin::linear_scan_loop_end_flag)) output()->print("\"lle\" "); | |
309 output()->cr(); | |
310 | |
311 if (block->dominator() != NULL) { | |
312 print("dominator \"B%d\"", block->dominator()->block_id()); | |
313 } | |
314 if (block->loop_index() != -1) { | |
315 print("loop_index %d", block->loop_index()); | |
316 print("loop_depth %d", block->loop_depth()); | |
317 } | |
318 | |
319 if (block->first_lir_instruction_id() != -1) { | |
320 print("first_lir_id %d", block->first_lir_instruction_id()); | |
321 print("last_lir_id %d", block->last_lir_instruction_id()); | |
322 } | |
323 | |
324 if (_do_print_HIR) { | |
325 print_state(block); | |
326 print_HIR(block); | |
327 } | |
328 | |
329 if (_do_print_LIR) { | |
330 print_LIR(block); | |
331 } | |
332 | |
333 print_end("block"); | |
334 } | |
335 | |
336 | |
337 | |
338 void CFGPrinterOutput::print_cfg(BlockList* blocks, const char* name) { | |
339 print_begin("cfg"); | |
340 print("name \"%s\"", name); | |
341 | |
342 PrintBlockClosure print_block; | |
343 blocks->iterate_forward(&print_block); | |
344 | |
345 print_end("cfg"); | |
346 output()->flush(); | |
347 } | |
348 | |
349 void CFGPrinterOutput::print_cfg(IR* blocks, const char* name) { | |
350 print_begin("cfg"); | |
351 print("name \"%s\"", name); | |
352 | |
353 PrintBlockClosure print_block; | |
354 blocks->iterate_preorder(&print_block); | |
355 | |
356 print_end("cfg"); | |
357 output()->flush(); | |
358 } | |
359 | |
360 | |
361 | |
362 | |
363 void CFGPrinterOutput::print_intervals(IntervalList* intervals, const char* name) { | |
364 print_begin("intervals"); | |
365 print("name \"%s\"", name); | |
366 | |
367 for (int i = 0; i < intervals->length(); i++) { | |
368 if (intervals->at(i) != NULL) { | |
369 intervals->at(i)->print(output()); | |
370 } | |
371 } | |
372 | |
373 print_end("intervals"); | |
374 output()->flush(); | |
375 } | |
376 | |
377 | |
378 #endif |