Mercurial > hg > truffle
annotate src/share/vm/opto/idealGraphPrinter.cpp @ 1145:e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking.
Reviewed-by: jmasa
author | ysr |
---|---|
date | Wed, 23 Dec 2009 09:23:54 -0800 |
parents | 0fbdb4381b99 |
children | f03d0a26bf83 |
rev | line source |
---|---|
0 | 1 /* |
579 | 2 * Copyright 2007-2009 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_idealGraphPrinter.cpp.incl" | |
27 | |
28 #ifndef PRODUCT | |
29 | |
30 // Constants | |
31 // Keep consistent with Java constants | |
32 const char *IdealGraphPrinter::INDENT = " "; | |
33 const char *IdealGraphPrinter::TOP_ELEMENT = "graphDocument"; | |
34 const char *IdealGraphPrinter::GROUP_ELEMENT = "group"; | |
35 const char *IdealGraphPrinter::GRAPH_ELEMENT = "graph"; | |
36 const char *IdealGraphPrinter::PROPERTIES_ELEMENT = "properties"; | |
37 const char *IdealGraphPrinter::EDGES_ELEMENT = "edges"; | |
38 const char *IdealGraphPrinter::PROPERTY_ELEMENT = "p"; | |
39 const char *IdealGraphPrinter::EDGE_ELEMENT = "edge"; | |
40 const char *IdealGraphPrinter::NODE_ELEMENT = "node"; | |
41 const char *IdealGraphPrinter::NODES_ELEMENT = "nodes"; | |
42 const char *IdealGraphPrinter::REMOVE_EDGE_ELEMENT = "removeEdge"; | |
43 const char *IdealGraphPrinter::REMOVE_NODE_ELEMENT = "removeNode"; | |
44 const char *IdealGraphPrinter::METHOD_NAME_PROPERTY = "name"; | |
45 const char *IdealGraphPrinter::METHOD_IS_PUBLIC_PROPERTY = "public"; | |
46 const char *IdealGraphPrinter::METHOD_IS_STATIC_PROPERTY = "static"; | |
47 const char *IdealGraphPrinter::TRUE_VALUE = "true"; | |
48 const char *IdealGraphPrinter::NODE_NAME_PROPERTY = "name"; | |
49 const char *IdealGraphPrinter::EDGE_NAME_PROPERTY = "name"; | |
50 const char *IdealGraphPrinter::NODE_ID_PROPERTY = "id"; | |
51 const char *IdealGraphPrinter::FROM_PROPERTY = "from"; | |
52 const char *IdealGraphPrinter::TO_PROPERTY = "to"; | |
53 const char *IdealGraphPrinter::PROPERTY_NAME_PROPERTY = "name"; | |
54 const char *IdealGraphPrinter::GRAPH_NAME_PROPERTY = "name"; | |
55 const char *IdealGraphPrinter::INDEX_PROPERTY = "index"; | |
56 const char *IdealGraphPrinter::METHOD_ELEMENT = "method"; | |
57 const char *IdealGraphPrinter::INLINE_ELEMENT = "inline"; | |
58 const char *IdealGraphPrinter::BYTECODES_ELEMENT = "bytecodes"; | |
59 const char *IdealGraphPrinter::METHOD_BCI_PROPERTY = "bci"; | |
60 const char *IdealGraphPrinter::METHOD_SHORT_NAME_PROPERTY = "shortName"; | |
61 const char *IdealGraphPrinter::CONTROL_FLOW_ELEMENT = "controlFlow"; | |
62 const char *IdealGraphPrinter::BLOCK_NAME_PROPERTY = "name"; | |
63 const char *IdealGraphPrinter::BLOCK_DOMINATOR_PROPERTY = "dom"; | |
64 const char *IdealGraphPrinter::BLOCK_ELEMENT = "block"; | |
65 const char *IdealGraphPrinter::SUCCESSORS_ELEMENT = "successors"; | |
66 const char *IdealGraphPrinter::SUCCESSOR_ELEMENT = "successor"; | |
67 const char *IdealGraphPrinter::ASSEMBLY_ELEMENT = "assembly"; | |
68 | |
69 int IdealGraphPrinter::_file_count = 0; | |
70 | |
71 IdealGraphPrinter *IdealGraphPrinter::printer() { | |
72 if (PrintIdealGraphLevel == 0) return NULL; | |
73 | |
74 JavaThread *thread = JavaThread::current(); | |
75 if (!thread->is_Compiler_thread()) return NULL; | |
76 | |
77 CompilerThread *compiler_thread = (CompilerThread *)thread; | |
78 if (compiler_thread->ideal_graph_printer() == NULL) { | |
79 IdealGraphPrinter *printer = new IdealGraphPrinter(); | |
80 compiler_thread->set_ideal_graph_printer(printer); | |
81 } | |
82 | |
83 return compiler_thread->ideal_graph_printer(); | |
84 } | |
85 | |
86 void IdealGraphPrinter::clean_up() { | |
87 JavaThread *p; | |
88 for (p = Threads::first(); p; p = p->next()) { | |
89 if (p->is_Compiler_thread()) { | |
90 CompilerThread *c = (CompilerThread *)p; | |
91 IdealGraphPrinter *printer = c->ideal_graph_printer(); | |
92 if (printer) { | |
93 delete printer; | |
94 } | |
95 c->set_ideal_graph_printer(NULL); | |
96 } | |
97 } | |
98 } | |
99 | |
100 // Constructor, either file or network output | |
101 IdealGraphPrinter::IdealGraphPrinter() { | |
102 | |
222 | 103 // By default dump both ins and outs since dead or unreachable code |
104 // needs to appear in the graph. There are also some special cases | |
105 // in the mach where kill projections have no users but should | |
106 // appear in the dump. | |
107 _traverse_outs = true; | |
0 | 108 _should_send_method = true; |
109 _output = NULL; | |
110 buffer[0] = 0; | |
111 _depth = 0; | |
112 _current_method = NULL; | |
113 assert(!_current_method, "current method must be initialized to NULL"); | |
222 | 114 _stream = NULL; |
0 | 115 |
116 if (PrintIdealGraphFile != NULL) { | |
117 ThreadCritical tc; | |
118 // User wants all output to go to files | |
119 if (_file_count != 0) { | |
120 ResourceMark rm; | |
121 stringStream st; | |
122 const char* dot = strrchr(PrintIdealGraphFile, '.'); | |
123 if (dot) { | |
124 st.write(PrintIdealGraphFile, dot - PrintIdealGraphFile); | |
125 st.print("%d%s", _file_count, dot); | |
126 } else { | |
127 st.print("%s%d", PrintIdealGraphFile, _file_count); | |
128 } | |
222 | 129 fileStream *stream = new (ResourceObj::C_HEAP) fileStream(st.as_string()); |
130 _output = stream; | |
0 | 131 } else { |
222 | 132 fileStream *stream = new (ResourceObj::C_HEAP) fileStream(PrintIdealGraphFile); |
133 _output = stream; | |
0 | 134 } |
135 _file_count++; | |
136 } else { | |
222 | 137 _stream = new (ResourceObj::C_HEAP) networkStream(); |
138 | |
0 | 139 // Try to connect to visualizer |
140 if (_stream->connect(PrintIdealGraphAddress, PrintIdealGraphPort)) { | |
141 char c = 0; | |
142 _stream->read(&c, 1); | |
143 if (c != 'y') { | |
144 tty->print_cr("Client available, but does not want to receive data!"); | |
145 _stream->close(); | |
146 delete _stream; | |
147 _stream = NULL; | |
148 return; | |
149 } | |
150 _output = _stream; | |
151 } else { | |
152 // It would be nice if we could shut down cleanly but it should | |
153 // be an error if we can't connect to the visualizer. | |
154 fatal2("Couldn't connect to visualizer at %s:%d", PrintIdealGraphAddress, PrintIdealGraphPort); | |
155 } | |
156 } | |
157 | |
222 | 158 _xml = new (ResourceObj::C_HEAP) xmlStream(_output); |
159 | |
160 head(TOP_ELEMENT); | |
0 | 161 } |
162 | |
163 // Destructor, close file or network stream | |
164 IdealGraphPrinter::~IdealGraphPrinter() { | |
165 | |
222 | 166 tail(TOP_ELEMENT); |
167 | |
168 // tty->print_cr("Walk time: %d", (int)_walk_time.milliseconds()); | |
169 // tty->print_cr("Output time: %d", (int)_output_time.milliseconds()); | |
170 // tty->print_cr("Build blocks time: %d", (int)_build_blocks_time.milliseconds()); | |
171 | |
172 if(_xml) { | |
173 delete _xml; | |
174 _xml = NULL; | |
175 } | |
0 | 176 |
177 if (_stream) { | |
178 delete _stream; | |
179 if (_stream == _output) { | |
180 _output = NULL; | |
181 } | |
182 _stream = NULL; | |
183 } | |
184 | |
185 if (_output) { | |
186 delete _output; | |
187 _output = NULL; | |
188 } | |
189 } | |
190 | |
191 | |
222 | 192 void IdealGraphPrinter::begin_elem(const char *s) { |
193 _xml->begin_elem(s); | |
194 } | |
195 | |
196 void IdealGraphPrinter::end_elem() { | |
197 _xml->end_elem(); | |
198 } | |
0 | 199 |
222 | 200 void IdealGraphPrinter::begin_head(const char *s) { |
201 _xml->begin_head(s); | |
202 } | |
0 | 203 |
222 | 204 void IdealGraphPrinter::end_head() { |
205 _xml->end_head(); | |
206 } | |
0 | 207 |
222 | 208 void IdealGraphPrinter::print_attr(const char *name, intptr_t val) { |
209 stringStream stream; | |
210 stream.print(INTX_FORMAT, val); | |
211 print_attr(name, stream.as_string()); | |
212 } | |
0 | 213 |
222 | 214 void IdealGraphPrinter::print_attr(const char *name, const char *val) { |
215 _xml->print(" %s='", name); | |
216 text(val); | |
217 _xml->print("'"); | |
218 } | |
0 | 219 |
222 | 220 void IdealGraphPrinter::head(const char *name) { |
221 _xml->head(name); | |
222 } | |
223 | |
224 void IdealGraphPrinter::tail(const char *name) { | |
225 _xml->tail(name); | |
226 } | |
0 | 227 |
222 | 228 void IdealGraphPrinter::text(const char *s) { |
229 _xml->text(s); | |
230 } | |
231 | |
232 void IdealGraphPrinter::print_prop(const char *name, int val) { | |
0 | 233 |
222 | 234 stringStream stream; |
235 stream.print("%d", val); | |
236 print_prop(name, stream.as_string()); | |
237 } | |
238 | |
239 void IdealGraphPrinter::print_prop(const char *name, const char *val) { | |
240 begin_head(PROPERTY_ELEMENT); | |
241 print_attr(PROPERTY_NAME_PROPERTY, name); | |
242 end_head(); | |
243 text(val); | |
244 tail(PROPERTY_ELEMENT); | |
0 | 245 } |
246 | |
247 void IdealGraphPrinter::print_method(ciMethod *method, int bci, InlineTree *tree) { | |
222 | 248 begin_head(METHOD_ELEMENT); |
0 | 249 |
250 stringStream str; | |
251 method->print_name(&str); | |
252 | |
253 stringStream shortStr; | |
254 method->print_short_name(&shortStr); | |
255 | |
222 | 256 print_attr(METHOD_NAME_PROPERTY, str.as_string()); |
257 print_attr(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string()); | |
258 print_attr(METHOD_BCI_PROPERTY, bci); | |
0 | 259 |
222 | 260 end_head(); |
0 | 261 |
222 | 262 head(BYTECODES_ELEMENT); |
0 | 263 output()->print_cr("<![CDATA["); |
264 method->print_codes_on(output()); | |
265 output()->print_cr("]]>"); | |
222 | 266 tail(BYTECODES_ELEMENT); |
0 | 267 |
222 | 268 head(INLINE_ELEMENT); |
0 | 269 if (tree != NULL) { |
270 GrowableArray<InlineTree *> subtrees = tree->subtrees(); | |
271 for (int i = 0; i < subtrees.length(); i++) { | |
272 print_inline_tree(subtrees.at(i)); | |
273 } | |
274 } | |
222 | 275 tail(INLINE_ELEMENT); |
0 | 276 |
222 | 277 tail(METHOD_ELEMENT); |
0 | 278 output()->flush(); |
279 } | |
280 | |
281 void IdealGraphPrinter::print_inline_tree(InlineTree *tree) { | |
282 | |
283 if (tree == NULL) return; | |
284 | |
285 ciMethod *method = tree->method(); | |
286 print_method(tree->method(), tree->caller_bci(), tree); | |
287 | |
288 } | |
289 | |
290 void IdealGraphPrinter::print_inlining(Compile* compile) { | |
291 | |
292 // Print inline tree | |
293 if (_should_send_method) { | |
294 InlineTree *inlineTree = compile->ilt(); | |
295 if (inlineTree != NULL) { | |
296 print_inline_tree(inlineTree); | |
297 } else { | |
298 // print this method only | |
299 } | |
300 } | |
301 } | |
302 | |
303 // Has to be called whenever a method is compiled | |
304 void IdealGraphPrinter::begin_method(Compile* compile) { | |
305 | |
306 ciMethod *method = compile->method(); | |
307 assert(_output, "output stream must exist!"); | |
308 assert(method, "null methods are not allowed!"); | |
309 assert(!_current_method, "current method must be null!"); | |
310 | |
222 | 311 head(GROUP_ELEMENT); |
0 | 312 |
222 | 313 head(PROPERTIES_ELEMENT); |
0 | 314 |
315 // Print properties | |
316 // Add method name | |
317 stringStream strStream; | |
318 method->print_name(&strStream); | |
222 | 319 print_prop(METHOD_NAME_PROPERTY, strStream.as_string()); |
0 | 320 |
321 if (method->flags().is_public()) { | |
222 | 322 print_prop(METHOD_IS_PUBLIC_PROPERTY, TRUE_VALUE); |
0 | 323 } |
324 | |
325 if (method->flags().is_static()) { | |
222 | 326 print_prop(METHOD_IS_STATIC_PROPERTY, TRUE_VALUE); |
0 | 327 } |
328 | |
222 | 329 tail(PROPERTIES_ELEMENT); |
0 | 330 |
331 if (_stream) { | |
332 char answer = 0; | |
222 | 333 _xml->flush(); |
0 | 334 int result = _stream->read(&answer, 1); |
335 _should_send_method = (answer == 'y'); | |
336 } | |
337 | |
338 this->_current_method = method; | |
339 | |
222 | 340 _xml->flush(); |
0 | 341 } |
342 | |
343 // Has to be called whenever a method has finished compilation | |
344 void IdealGraphPrinter::end_method() { | |
345 | |
346 nmethod* method = (nmethod*)this->_current_method->code(); | |
347 | |
222 | 348 tail(GROUP_ELEMENT); |
0 | 349 _current_method = NULL; |
222 | 350 _xml->flush(); |
0 | 351 } |
352 | |
353 // Print indent | |
354 void IdealGraphPrinter::print_indent() { | |
222 | 355 tty->print_cr("printing ident %d", _depth); |
0 | 356 for (int i = 0; i < _depth; i++) { |
222 | 357 _xml->print(INDENT); |
0 | 358 } |
359 } | |
360 | |
361 bool IdealGraphPrinter::traverse_outs() { | |
362 return _traverse_outs; | |
363 } | |
364 | |
365 void IdealGraphPrinter::set_traverse_outs(bool b) { | |
366 _traverse_outs = b; | |
367 } | |
368 | |
222 | 369 intptr_t IdealGraphPrinter::get_node_id(Node *n) { |
370 return (intptr_t)(n); | |
371 } | |
372 | |
373 void IdealGraphPrinter::visit_node(Node *n, void *param) { | |
374 | |
375 if(param) { | |
376 | |
377 // Output edge | |
378 intptr_t dest_id = get_node_id(n); | |
379 for ( uint i = 0; i < n->len(); i++ ) { | |
380 if ( n->in(i) ) { | |
381 Node *source = n->in(i); | |
382 begin_elem(EDGE_ELEMENT); | |
383 intptr_t source_id = get_node_id(source); | |
384 print_attr(FROM_PROPERTY, source_id); | |
385 print_attr(TO_PROPERTY, dest_id); | |
386 print_attr(INDEX_PROPERTY, i); | |
387 end_elem(); | |
388 } | |
389 } | |
390 | |
391 } else { | |
392 | |
393 // Output node | |
394 begin_head(NODE_ELEMENT); | |
395 print_attr(NODE_ID_PROPERTY, get_node_id(n)); | |
396 end_head(); | |
397 | |
398 head(PROPERTIES_ELEMENT); | |
399 | |
400 Node *node = n; | |
401 #ifndef PRODUCT | |
402 node->_in_dump_cnt++; | |
403 print_prop(NODE_NAME_PROPERTY, (const char *)node->Name()); | |
404 const Type *t = node->bottom_type(); | |
405 print_prop("type", (const char *)Type::msg[t->base()]); | |
406 print_prop("idx", node->_idx); | |
407 #ifdef ASSERT | |
408 print_prop("debug_idx", node->_debug_idx); | |
409 #endif | |
410 | |
411 if(C->cfg() != NULL) { | |
412 Block *block = C->cfg()->_bbs[node->_idx]; | |
413 if(block == NULL) { | |
414 print_prop("block", C->cfg()->_blocks[0]->_pre_order); | |
415 } else { | |
416 print_prop("block", block->_pre_order); | |
417 } | |
418 } | |
419 | |
420 const jushort flags = node->flags(); | |
421 if (flags & Node::Flag_is_Copy) { | |
422 print_prop("is_copy", "true"); | |
423 } | |
424 if (flags & Node::Flag_is_Call) { | |
425 print_prop("is_call", "true"); | |
426 } | |
427 if (flags & Node::Flag_rematerialize) { | |
428 print_prop("rematerialize", "true"); | |
429 } | |
430 if (flags & Node::Flag_needs_anti_dependence_check) { | |
431 print_prop("needs_anti_dependence_check", "true"); | |
432 } | |
433 if (flags & Node::Flag_is_macro) { | |
434 print_prop("is_macro", "true"); | |
435 } | |
436 if (flags & Node::Flag_is_Con) { | |
437 print_prop("is_con", "true"); | |
438 } | |
439 if (flags & Node::Flag_is_cisc_alternate) { | |
440 print_prop("is_cisc_alternate", "true"); | |
441 } | |
442 if (flags & Node::Flag_is_Branch) { | |
443 print_prop("is_branch", "true"); | |
444 } | |
445 if (flags & Node::Flag_is_block_start) { | |
446 print_prop("is_block_start", "true"); | |
447 } | |
448 if (flags & Node::Flag_is_Goto) { | |
449 print_prop("is_goto", "true"); | |
450 } | |
451 if (flags & Node::Flag_is_dead_loop_safe) { | |
452 print_prop("is_dead_loop_safe", "true"); | |
453 } | |
454 if (flags & Node::Flag_may_be_short_branch) { | |
455 print_prop("may_be_short_branch", "true"); | |
456 } | |
457 if (flags & Node::Flag_is_safepoint_node) { | |
458 print_prop("is_safepoint_node", "true"); | |
459 } | |
460 if (flags & Node::Flag_is_pc_relative) { | |
461 print_prop("is_pc_relative", "true"); | |
462 } | |
463 | |
464 if (C->matcher() != NULL) { | |
465 if (C->matcher()->is_shared(node)) { | |
466 print_prop("is_shared", "true"); | |
467 } else { | |
468 print_prop("is_shared", "false"); | |
469 } | |
470 if (C->matcher()->is_dontcare(node)) { | |
471 print_prop("is_dontcare", "true"); | |
472 } else { | |
473 print_prop("is_dontcare", "false"); | |
474 } | |
475 | |
250
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
222
diff
changeset
|
476 #ifdef ASSERT |
222 | 477 Node* old = C->matcher()->find_old_node(node); |
478 if (old != NULL) { | |
479 print_prop("old_node_idx", old->_idx); | |
480 } | |
250
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
222
diff
changeset
|
481 #endif |
222 | 482 } |
483 | |
484 if (node->is_Proj()) { | |
485 print_prop("con", (int)node->as_Proj()->_con); | |
486 } | |
487 | |
488 if (node->is_Mach()) { | |
489 print_prop("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()]); | |
490 } | |
491 | |
492 buffer[0] = 0; | |
493 stringStream s2(buffer, sizeof(buffer) - 1); | |
494 | |
495 node->dump_spec(&s2); | |
496 if (t != NULL && (t->isa_instptr() || t->isa_klassptr())) { | |
497 const TypeInstPtr *toop = t->isa_instptr(); | |
498 const TypeKlassPtr *tkls = t->isa_klassptr(); | |
499 ciKlass* klass = toop ? toop->klass() : (tkls ? tkls->klass() : NULL ); | |
500 if( klass && klass->is_loaded() && klass->is_interface() ) { | |
501 s2.print(" Interface:"); | |
502 } else if( toop ) { | |
503 s2.print(" Oop:"); | |
504 } else if( tkls ) { | |
505 s2.print(" Klass:"); | |
506 } | |
507 t->dump_on(&s2); | |
508 } else if( t == Type::MEMORY ) { | |
509 s2.print(" Memory:"); | |
510 MemNode::dump_adr_type(node, node->adr_type(), &s2); | |
511 } | |
512 | |
513 assert(s2.size() < sizeof(buffer), "size in range"); | |
514 print_prop("dump_spec", buffer); | |
515 | |
516 if (node->is_block_proj()) { | |
517 print_prop("is_block_proj", "true"); | |
518 } | |
519 | |
520 if (node->is_block_start()) { | |
521 print_prop("is_block_start", "true"); | |
522 } | |
523 | |
524 const char *short_name = "short_name"; | |
525 if (strcmp(node->Name(), "Parm") == 0 && node->as_Proj()->_con >= TypeFunc::Parms) { | |
526 int index = node->as_Proj()->_con - TypeFunc::Parms; | |
527 if (index >= 10) { | |
528 print_prop(short_name, "PA"); | |
529 } else { | |
530 sprintf(buffer, "P%d", index); | |
531 print_prop(short_name, buffer); | |
532 } | |
533 } else if (strcmp(node->Name(), "IfTrue") == 0) { | |
534 print_prop(short_name, "T"); | |
535 } else if (strcmp(node->Name(), "IfFalse") == 0) { | |
536 print_prop(short_name, "F"); | |
537 } else if ((node->is_Con() && node->is_Type()) || node->is_Proj()) { | |
538 | |
539 if (t->base() == Type::Int && t->is_int()->is_con()) { | |
540 const TypeInt *typeInt = t->is_int(); | |
541 assert(typeInt->is_con(), "must be constant"); | |
542 jint value = typeInt->get_con(); | |
543 | |
544 // max. 2 chars allowed | |
545 if (value >= -9 && value <= 99) { | |
546 sprintf(buffer, "%d", value); | |
547 print_prop(short_name, buffer); | |
548 } else { | |
549 print_prop(short_name, "I"); | |
550 } | |
551 } else if (t == Type::TOP) { | |
552 print_prop(short_name, "^"); | |
553 } else if (t->base() == Type::Long && t->is_long()->is_con()) { | |
554 const TypeLong *typeLong = t->is_long(); | |
555 assert(typeLong->is_con(), "must be constant"); | |
556 jlong value = typeLong->get_con(); | |
557 | |
558 // max. 2 chars allowed | |
559 if (value >= -9 && value <= 99) { | |
513
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
337
diff
changeset
|
560 sprintf(buffer, INT64_FORMAT, value); |
222 | 561 print_prop(short_name, buffer); |
562 } else { | |
563 print_prop(short_name, "L"); | |
564 } | |
565 } else if (t->base() == Type::KlassPtr) { | |
566 const TypeKlassPtr *typeKlass = t->is_klassptr(); | |
567 print_prop(short_name, "CP"); | |
568 } else if (t->base() == Type::Control) { | |
569 print_prop(short_name, "C"); | |
570 } else if (t->base() == Type::Memory) { | |
571 print_prop(short_name, "M"); | |
572 } else if (t->base() == Type::Abio) { | |
573 print_prop(short_name, "IO"); | |
574 } else if (t->base() == Type::Return_Address) { | |
575 print_prop(short_name, "RA"); | |
576 } else if (t->base() == Type::AnyPtr) { | |
577 print_prop(short_name, "P"); | |
578 } else if (t->base() == Type::RawPtr) { | |
579 print_prop(short_name, "RP"); | |
580 } else if (t->base() == Type::AryPtr) { | |
581 print_prop(short_name, "AP"); | |
582 } | |
583 } | |
584 | |
585 JVMState* caller = NULL; | |
586 if (node->is_SafePoint()) { | |
587 caller = node->as_SafePoint()->jvms(); | |
588 } else { | |
589 Node_Notes* notes = C->node_notes_at(node->_idx); | |
590 if (notes != NULL) { | |
591 caller = notes->jvms(); | |
592 } | |
593 } | |
594 | |
595 if (caller != NULL) { | |
596 stringStream bciStream; | |
597 while(caller) { | |
598 bciStream.print("%d ", caller->bci()); | |
599 caller = caller->caller(); | |
600 } | |
601 print_prop("bci", bciStream.as_string()); | |
602 } | |
603 | |
604 if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) { | |
605 buffer[0] = 0; | |
606 _chaitin->dump_register(node, buffer); | |
607 print_prop("reg", buffer); | |
608 print_prop("lrg", _chaitin->n2lidx(node)); | |
609 } | |
610 | |
611 node->_in_dump_cnt--; | |
612 #endif | |
613 | |
614 tail(PROPERTIES_ELEMENT); | |
615 tail(NODE_ELEMENT); | |
616 } | |
617 } | |
618 | |
619 void IdealGraphPrinter::walk_nodes(Node *start, void *param) { | |
0 | 620 |
621 | |
622 VectorSet visited(Thread::current()->resource_area()); | |
623 GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, NULL); | |
624 nodeStack.push(start); | |
625 visited.test_set(start->_idx); | |
626 while(nodeStack.length() > 0) { | |
627 | |
628 Node *n = nodeStack.pop(); | |
222 | 629 visit_node(n, param); |
0 | 630 |
631 if (_traverse_outs) { | |
632 for (DUIterator i = n->outs(); n->has_out(i); i++) { | |
633 Node* p = n->out(i); | |
634 if (!visited.test_set(p->_idx)) { | |
635 nodeStack.push(p); | |
636 } | |
637 } | |
638 } | |
639 | |
640 for ( uint i = 0; i < n->len(); i++ ) { | |
641 if ( n->in(i) ) { | |
642 if (!visited.test_set(n->in(i)->_idx)) { | |
643 nodeStack.push(n->in(i)); | |
644 } | |
645 } | |
646 } | |
647 } | |
648 } | |
649 | |
650 void IdealGraphPrinter::print_method(Compile* compile, const char *name, int level, bool clear_nodes) { | |
651 print(compile, name, (Node *)compile->root(), level, clear_nodes); | |
652 } | |
653 | |
654 // Print current ideal graph | |
655 void IdealGraphPrinter::print(Compile* compile, const char *name, Node *node, int level, bool clear_nodes) { | |
656 | |
657 if (!_current_method || !_should_send_method || level > PrintIdealGraphLevel) return; | |
658 | |
222 | 659 this->C = compile; |
0 | 660 |
661 // Warning, unsafe cast? | |
222 | 662 _chaitin = (PhaseChaitin *)C->regalloc(); |
0 | 663 |
222 | 664 begin_head(GRAPH_ELEMENT); |
665 print_attr(GRAPH_NAME_PROPERTY, (const char *)name); | |
666 end_head(); | |
0 | 667 |
222 | 668 head(NODES_ELEMENT); |
669 walk_nodes(node, NULL); | |
670 tail(NODES_ELEMENT); | |
0 | 671 |
222 | 672 head(EDGES_ELEMENT); |
673 walk_nodes(node, (void *)1); | |
674 tail(EDGES_ELEMENT); | |
675 if (C->cfg() != NULL) { | |
676 head(CONTROL_FLOW_ELEMENT); | |
677 for (uint i = 0; i < C->cfg()->_blocks.size(); i++) { | |
678 Block *b = C->cfg()->_blocks[i]; | |
679 begin_head(BLOCK_ELEMENT); | |
680 print_attr(BLOCK_NAME_PROPERTY, b->_pre_order); | |
681 end_head(); | |
0 | 682 |
222 | 683 head(SUCCESSORS_ELEMENT); |
684 for (uint s = 0; s < C->cfg()->_blocks[i]->_num_succs; s++) { | |
685 begin_elem(SUCCESSOR_ELEMENT); | |
686 print_attr(BLOCK_NAME_PROPERTY, b->_succs[s]->_pre_order); | |
687 end_elem(); | |
0 | 688 } |
222 | 689 tail(SUCCESSORS_ELEMENT); |
0 | 690 |
222 | 691 tail(BLOCK_ELEMENT); |
692 } | |
0 | 693 |
222 | 694 tail(CONTROL_FLOW_ELEMENT); |
0 | 695 } |
222 | 696 tail(GRAPH_ELEMENT); |
697 output()->flush(); | |
0 | 698 } |
699 | |
700 extern const char *NodeClassNames[]; | |
701 | |
702 outputStream *IdealGraphPrinter::output() { | |
222 | 703 return _xml; |
0 | 704 } |
705 | |
706 #endif |