Mercurial > hg > truffle
annotate src/share/vm/c1/c1_CFGPrinter.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | d2a62e0f25eb |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2005, 2010, 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 | |
36 class CFGPrinterOutput : public CHeapObj { | |
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() | |
109 : _output(new(ResourceObj::C_HEAP) fileStream("output.cfg")) | |
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 |