Mercurial > hg > truffle
annotate src/share/vm/opto/idealGraphPrinter.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
2 * Copyright (c) 2007, 2009, 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:
1490
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
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:
1490
diff
changeset
|
21 * questions. |
0 | 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. | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
579
diff
changeset
|
154 fatal(err_msg("Couldn't connect to visualizer at %s:%d", |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
579
diff
changeset
|
155 PrintIdealGraphAddress, PrintIdealGraphPort)); |
0 | 156 } |
157 } | |
158 | |
222 | 159 _xml = new (ResourceObj::C_HEAP) xmlStream(_output); |
160 | |
161 head(TOP_ELEMENT); | |
0 | 162 } |
163 | |
164 // Destructor, close file or network stream | |
165 IdealGraphPrinter::~IdealGraphPrinter() { | |
166 | |
222 | 167 tail(TOP_ELEMENT); |
168 | |
169 // tty->print_cr("Walk time: %d", (int)_walk_time.milliseconds()); | |
170 // tty->print_cr("Output time: %d", (int)_output_time.milliseconds()); | |
171 // tty->print_cr("Build blocks time: %d", (int)_build_blocks_time.milliseconds()); | |
172 | |
173 if(_xml) { | |
174 delete _xml; | |
175 _xml = NULL; | |
176 } | |
0 | 177 |
178 if (_stream) { | |
179 delete _stream; | |
180 if (_stream == _output) { | |
181 _output = NULL; | |
182 } | |
183 _stream = NULL; | |
184 } | |
185 | |
186 if (_output) { | |
187 delete _output; | |
188 _output = NULL; | |
189 } | |
190 } | |
191 | |
192 | |
222 | 193 void IdealGraphPrinter::begin_elem(const char *s) { |
194 _xml->begin_elem(s); | |
195 } | |
196 | |
197 void IdealGraphPrinter::end_elem() { | |
198 _xml->end_elem(); | |
199 } | |
0 | 200 |
222 | 201 void IdealGraphPrinter::begin_head(const char *s) { |
202 _xml->begin_head(s); | |
203 } | |
0 | 204 |
222 | 205 void IdealGraphPrinter::end_head() { |
206 _xml->end_head(); | |
207 } | |
0 | 208 |
222 | 209 void IdealGraphPrinter::print_attr(const char *name, intptr_t val) { |
210 stringStream stream; | |
211 stream.print(INTX_FORMAT, val); | |
212 print_attr(name, stream.as_string()); | |
213 } | |
0 | 214 |
222 | 215 void IdealGraphPrinter::print_attr(const char *name, const char *val) { |
216 _xml->print(" %s='", name); | |
217 text(val); | |
218 _xml->print("'"); | |
219 } | |
0 | 220 |
222 | 221 void IdealGraphPrinter::head(const char *name) { |
222 _xml->head(name); | |
223 } | |
224 | |
225 void IdealGraphPrinter::tail(const char *name) { | |
226 _xml->tail(name); | |
227 } | |
0 | 228 |
222 | 229 void IdealGraphPrinter::text(const char *s) { |
230 _xml->text(s); | |
231 } | |
232 | |
233 void IdealGraphPrinter::print_prop(const char *name, int val) { | |
0 | 234 |
222 | 235 stringStream stream; |
236 stream.print("%d", val); | |
237 print_prop(name, stream.as_string()); | |
238 } | |
239 | |
240 void IdealGraphPrinter::print_prop(const char *name, const char *val) { | |
241 begin_head(PROPERTY_ELEMENT); | |
242 print_attr(PROPERTY_NAME_PROPERTY, name); | |
243 end_head(); | |
244 text(val); | |
245 tail(PROPERTY_ELEMENT); | |
0 | 246 } |
247 | |
248 void IdealGraphPrinter::print_method(ciMethod *method, int bci, InlineTree *tree) { | |
222 | 249 begin_head(METHOD_ELEMENT); |
0 | 250 |
251 stringStream str; | |
252 method->print_name(&str); | |
253 | |
254 stringStream shortStr; | |
255 method->print_short_name(&shortStr); | |
256 | |
222 | 257 print_attr(METHOD_NAME_PROPERTY, str.as_string()); |
258 print_attr(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string()); | |
259 print_attr(METHOD_BCI_PROPERTY, bci); | |
0 | 260 |
222 | 261 end_head(); |
0 | 262 |
222 | 263 head(BYTECODES_ELEMENT); |
0 | 264 output()->print_cr("<![CDATA["); |
265 method->print_codes_on(output()); | |
266 output()->print_cr("]]>"); | |
222 | 267 tail(BYTECODES_ELEMENT); |
0 | 268 |
222 | 269 head(INLINE_ELEMENT); |
0 | 270 if (tree != NULL) { |
271 GrowableArray<InlineTree *> subtrees = tree->subtrees(); | |
272 for (int i = 0; i < subtrees.length(); i++) { | |
273 print_inline_tree(subtrees.at(i)); | |
274 } | |
275 } | |
222 | 276 tail(INLINE_ELEMENT); |
0 | 277 |
222 | 278 tail(METHOD_ELEMENT); |
0 | 279 output()->flush(); |
280 } | |
281 | |
282 void IdealGraphPrinter::print_inline_tree(InlineTree *tree) { | |
283 | |
284 if (tree == NULL) return; | |
285 | |
286 ciMethod *method = tree->method(); | |
287 print_method(tree->method(), tree->caller_bci(), tree); | |
288 | |
289 } | |
290 | |
291 void IdealGraphPrinter::print_inlining(Compile* compile) { | |
292 | |
293 // Print inline tree | |
294 if (_should_send_method) { | |
295 InlineTree *inlineTree = compile->ilt(); | |
296 if (inlineTree != NULL) { | |
297 print_inline_tree(inlineTree); | |
298 } else { | |
299 // print this method only | |
300 } | |
301 } | |
302 } | |
303 | |
304 // Has to be called whenever a method is compiled | |
305 void IdealGraphPrinter::begin_method(Compile* compile) { | |
306 | |
307 ciMethod *method = compile->method(); | |
308 assert(_output, "output stream must exist!"); | |
309 assert(method, "null methods are not allowed!"); | |
310 assert(!_current_method, "current method must be null!"); | |
311 | |
222 | 312 head(GROUP_ELEMENT); |
0 | 313 |
222 | 314 head(PROPERTIES_ELEMENT); |
0 | 315 |
316 // Print properties | |
317 // Add method name | |
318 stringStream strStream; | |
319 method->print_name(&strStream); | |
222 | 320 print_prop(METHOD_NAME_PROPERTY, strStream.as_string()); |
0 | 321 |
322 if (method->flags().is_public()) { | |
222 | 323 print_prop(METHOD_IS_PUBLIC_PROPERTY, TRUE_VALUE); |
0 | 324 } |
325 | |
326 if (method->flags().is_static()) { | |
222 | 327 print_prop(METHOD_IS_STATIC_PROPERTY, TRUE_VALUE); |
0 | 328 } |
329 | |
222 | 330 tail(PROPERTIES_ELEMENT); |
0 | 331 |
332 if (_stream) { | |
333 char answer = 0; | |
222 | 334 _xml->flush(); |
0 | 335 int result = _stream->read(&answer, 1); |
336 _should_send_method = (answer == 'y'); | |
337 } | |
338 | |
339 this->_current_method = method; | |
340 | |
222 | 341 _xml->flush(); |
0 | 342 } |
343 | |
344 // Has to be called whenever a method has finished compilation | |
345 void IdealGraphPrinter::end_method() { | |
346 | |
347 nmethod* method = (nmethod*)this->_current_method->code(); | |
348 | |
222 | 349 tail(GROUP_ELEMENT); |
0 | 350 _current_method = NULL; |
222 | 351 _xml->flush(); |
0 | 352 } |
353 | |
354 // Print indent | |
355 void IdealGraphPrinter::print_indent() { | |
222 | 356 tty->print_cr("printing ident %d", _depth); |
0 | 357 for (int i = 0; i < _depth; i++) { |
222 | 358 _xml->print(INDENT); |
0 | 359 } |
360 } | |
361 | |
362 bool IdealGraphPrinter::traverse_outs() { | |
363 return _traverse_outs; | |
364 } | |
365 | |
366 void IdealGraphPrinter::set_traverse_outs(bool b) { | |
367 _traverse_outs = b; | |
368 } | |
369 | |
222 | 370 intptr_t IdealGraphPrinter::get_node_id(Node *n) { |
371 return (intptr_t)(n); | |
372 } | |
373 | |
374 void IdealGraphPrinter::visit_node(Node *n, void *param) { | |
375 | |
376 if(param) { | |
377 | |
378 // Output edge | |
379 intptr_t dest_id = get_node_id(n); | |
380 for ( uint i = 0; i < n->len(); i++ ) { | |
381 if ( n->in(i) ) { | |
382 Node *source = n->in(i); | |
383 begin_elem(EDGE_ELEMENT); | |
384 intptr_t source_id = get_node_id(source); | |
385 print_attr(FROM_PROPERTY, source_id); | |
386 print_attr(TO_PROPERTY, dest_id); | |
387 print_attr(INDEX_PROPERTY, i); | |
388 end_elem(); | |
389 } | |
390 } | |
391 | |
392 } else { | |
393 | |
394 // Output node | |
395 begin_head(NODE_ELEMENT); | |
396 print_attr(NODE_ID_PROPERTY, get_node_id(n)); | |
397 end_head(); | |
398 | |
399 head(PROPERTIES_ELEMENT); | |
400 | |
401 Node *node = n; | |
402 #ifndef PRODUCT | |
403 node->_in_dump_cnt++; | |
404 print_prop(NODE_NAME_PROPERTY, (const char *)node->Name()); | |
405 const Type *t = node->bottom_type(); | |
406 print_prop("type", (const char *)Type::msg[t->base()]); | |
407 print_prop("idx", node->_idx); | |
408 #ifdef ASSERT | |
409 print_prop("debug_idx", node->_debug_idx); | |
410 #endif | |
411 | |
412 if(C->cfg() != NULL) { | |
413 Block *block = C->cfg()->_bbs[node->_idx]; | |
414 if(block == NULL) { | |
415 print_prop("block", C->cfg()->_blocks[0]->_pre_order); | |
416 } else { | |
417 print_prop("block", block->_pre_order); | |
418 } | |
419 } | |
420 | |
421 const jushort flags = node->flags(); | |
422 if (flags & Node::Flag_is_Copy) { | |
423 print_prop("is_copy", "true"); | |
424 } | |
425 if (flags & Node::Flag_is_Call) { | |
426 print_prop("is_call", "true"); | |
427 } | |
428 if (flags & Node::Flag_rematerialize) { | |
429 print_prop("rematerialize", "true"); | |
430 } | |
431 if (flags & Node::Flag_needs_anti_dependence_check) { | |
432 print_prop("needs_anti_dependence_check", "true"); | |
433 } | |
434 if (flags & Node::Flag_is_macro) { | |
435 print_prop("is_macro", "true"); | |
436 } | |
437 if (flags & Node::Flag_is_Con) { | |
438 print_prop("is_con", "true"); | |
439 } | |
440 if (flags & Node::Flag_is_cisc_alternate) { | |
441 print_prop("is_cisc_alternate", "true"); | |
442 } | |
443 if (flags & Node::Flag_is_Branch) { | |
444 print_prop("is_branch", "true"); | |
445 } | |
446 if (flags & Node::Flag_is_block_start) { | |
447 print_prop("is_block_start", "true"); | |
448 } | |
449 if (flags & Node::Flag_is_Goto) { | |
450 print_prop("is_goto", "true"); | |
451 } | |
452 if (flags & Node::Flag_is_dead_loop_safe) { | |
453 print_prop("is_dead_loop_safe", "true"); | |
454 } | |
455 if (flags & Node::Flag_may_be_short_branch) { | |
456 print_prop("may_be_short_branch", "true"); | |
457 } | |
458 if (flags & Node::Flag_is_safepoint_node) { | |
459 print_prop("is_safepoint_node", "true"); | |
460 } | |
461 if (flags & Node::Flag_is_pc_relative) { | |
462 print_prop("is_pc_relative", "true"); | |
463 } | |
464 | |
465 if (C->matcher() != NULL) { | |
466 if (C->matcher()->is_shared(node)) { | |
467 print_prop("is_shared", "true"); | |
468 } else { | |
469 print_prop("is_shared", "false"); | |
470 } | |
471 if (C->matcher()->is_dontcare(node)) { | |
472 print_prop("is_dontcare", "true"); | |
473 } else { | |
474 print_prop("is_dontcare", "false"); | |
475 } | |
476 | |
250
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
222
diff
changeset
|
477 #ifdef ASSERT |
222 | 478 Node* old = C->matcher()->find_old_node(node); |
479 if (old != NULL) { | |
480 print_prop("old_node_idx", old->_idx); | |
481 } | |
250
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
222
diff
changeset
|
482 #endif |
222 | 483 } |
484 | |
485 if (node->is_Proj()) { | |
486 print_prop("con", (int)node->as_Proj()->_con); | |
487 } | |
488 | |
489 if (node->is_Mach()) { | |
490 print_prop("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()]); | |
491 } | |
492 | |
493 buffer[0] = 0; | |
494 stringStream s2(buffer, sizeof(buffer) - 1); | |
495 | |
496 node->dump_spec(&s2); | |
497 if (t != NULL && (t->isa_instptr() || t->isa_klassptr())) { | |
498 const TypeInstPtr *toop = t->isa_instptr(); | |
499 const TypeKlassPtr *tkls = t->isa_klassptr(); | |
500 ciKlass* klass = toop ? toop->klass() : (tkls ? tkls->klass() : NULL ); | |
501 if( klass && klass->is_loaded() && klass->is_interface() ) { | |
502 s2.print(" Interface:"); | |
503 } else if( toop ) { | |
504 s2.print(" Oop:"); | |
505 } else if( tkls ) { | |
506 s2.print(" Klass:"); | |
507 } | |
508 t->dump_on(&s2); | |
509 } else if( t == Type::MEMORY ) { | |
510 s2.print(" Memory:"); | |
511 MemNode::dump_adr_type(node, node->adr_type(), &s2); | |
512 } | |
513 | |
514 assert(s2.size() < sizeof(buffer), "size in range"); | |
515 print_prop("dump_spec", buffer); | |
516 | |
517 if (node->is_block_proj()) { | |
518 print_prop("is_block_proj", "true"); | |
519 } | |
520 | |
521 if (node->is_block_start()) { | |
522 print_prop("is_block_start", "true"); | |
523 } | |
524 | |
525 const char *short_name = "short_name"; | |
526 if (strcmp(node->Name(), "Parm") == 0 && node->as_Proj()->_con >= TypeFunc::Parms) { | |
527 int index = node->as_Proj()->_con - TypeFunc::Parms; | |
528 if (index >= 10) { | |
529 print_prop(short_name, "PA"); | |
530 } else { | |
531 sprintf(buffer, "P%d", index); | |
532 print_prop(short_name, buffer); | |
533 } | |
534 } else if (strcmp(node->Name(), "IfTrue") == 0) { | |
535 print_prop(short_name, "T"); | |
536 } else if (strcmp(node->Name(), "IfFalse") == 0) { | |
537 print_prop(short_name, "F"); | |
538 } else if ((node->is_Con() && node->is_Type()) || node->is_Proj()) { | |
539 | |
540 if (t->base() == Type::Int && t->is_int()->is_con()) { | |
541 const TypeInt *typeInt = t->is_int(); | |
542 assert(typeInt->is_con(), "must be constant"); | |
543 jint value = typeInt->get_con(); | |
544 | |
545 // max. 2 chars allowed | |
546 if (value >= -9 && value <= 99) { | |
547 sprintf(buffer, "%d", value); | |
548 print_prop(short_name, buffer); | |
549 } else { | |
550 print_prop(short_name, "I"); | |
551 } | |
552 } else if (t == Type::TOP) { | |
553 print_prop(short_name, "^"); | |
554 } else if (t->base() == Type::Long && t->is_long()->is_con()) { | |
555 const TypeLong *typeLong = t->is_long(); | |
556 assert(typeLong->is_con(), "must be constant"); | |
557 jlong value = typeLong->get_con(); | |
558 | |
559 // max. 2 chars allowed | |
560 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
|
561 sprintf(buffer, INT64_FORMAT, value); |
222 | 562 print_prop(short_name, buffer); |
563 } else { | |
564 print_prop(short_name, "L"); | |
565 } | |
566 } else if (t->base() == Type::KlassPtr) { | |
567 const TypeKlassPtr *typeKlass = t->is_klassptr(); | |
568 print_prop(short_name, "CP"); | |
569 } else if (t->base() == Type::Control) { | |
570 print_prop(short_name, "C"); | |
571 } else if (t->base() == Type::Memory) { | |
572 print_prop(short_name, "M"); | |
573 } else if (t->base() == Type::Abio) { | |
574 print_prop(short_name, "IO"); | |
575 } else if (t->base() == Type::Return_Address) { | |
576 print_prop(short_name, "RA"); | |
577 } else if (t->base() == Type::AnyPtr) { | |
578 print_prop(short_name, "P"); | |
579 } else if (t->base() == Type::RawPtr) { | |
580 print_prop(short_name, "RP"); | |
581 } else if (t->base() == Type::AryPtr) { | |
582 print_prop(short_name, "AP"); | |
583 } | |
584 } | |
585 | |
586 JVMState* caller = NULL; | |
587 if (node->is_SafePoint()) { | |
588 caller = node->as_SafePoint()->jvms(); | |
589 } else { | |
590 Node_Notes* notes = C->node_notes_at(node->_idx); | |
591 if (notes != NULL) { | |
592 caller = notes->jvms(); | |
593 } | |
594 } | |
595 | |
596 if (caller != NULL) { | |
597 stringStream bciStream; | |
598 while(caller) { | |
599 bciStream.print("%d ", caller->bci()); | |
600 caller = caller->caller(); | |
601 } | |
602 print_prop("bci", bciStream.as_string()); | |
603 } | |
604 | |
605 if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) { | |
606 buffer[0] = 0; | |
607 _chaitin->dump_register(node, buffer); | |
608 print_prop("reg", buffer); | |
609 print_prop("lrg", _chaitin->n2lidx(node)); | |
610 } | |
611 | |
612 node->_in_dump_cnt--; | |
613 #endif | |
614 | |
615 tail(PROPERTIES_ELEMENT); | |
616 tail(NODE_ELEMENT); | |
617 } | |
618 } | |
619 | |
620 void IdealGraphPrinter::walk_nodes(Node *start, void *param) { | |
0 | 621 |
622 | |
623 VectorSet visited(Thread::current()->resource_area()); | |
624 GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, NULL); | |
625 nodeStack.push(start); | |
626 visited.test_set(start->_idx); | |
627 while(nodeStack.length() > 0) { | |
628 | |
629 Node *n = nodeStack.pop(); | |
222 | 630 visit_node(n, param); |
0 | 631 |
632 if (_traverse_outs) { | |
633 for (DUIterator i = n->outs(); n->has_out(i); i++) { | |
634 Node* p = n->out(i); | |
635 if (!visited.test_set(p->_idx)) { | |
636 nodeStack.push(p); | |
637 } | |
638 } | |
639 } | |
640 | |
641 for ( uint i = 0; i < n->len(); i++ ) { | |
642 if ( n->in(i) ) { | |
643 if (!visited.test_set(n->in(i)->_idx)) { | |
644 nodeStack.push(n->in(i)); | |
645 } | |
646 } | |
647 } | |
648 } | |
649 } | |
650 | |
651 void IdealGraphPrinter::print_method(Compile* compile, const char *name, int level, bool clear_nodes) { | |
652 print(compile, name, (Node *)compile->root(), level, clear_nodes); | |
653 } | |
654 | |
655 // Print current ideal graph | |
656 void IdealGraphPrinter::print(Compile* compile, const char *name, Node *node, int level, bool clear_nodes) { | |
657 | |
658 if (!_current_method || !_should_send_method || level > PrintIdealGraphLevel) return; | |
659 | |
222 | 660 this->C = compile; |
0 | 661 |
662 // Warning, unsafe cast? | |
222 | 663 _chaitin = (PhaseChaitin *)C->regalloc(); |
0 | 664 |
222 | 665 begin_head(GRAPH_ELEMENT); |
666 print_attr(GRAPH_NAME_PROPERTY, (const char *)name); | |
667 end_head(); | |
0 | 668 |
222 | 669 head(NODES_ELEMENT); |
670 walk_nodes(node, NULL); | |
671 tail(NODES_ELEMENT); | |
0 | 672 |
222 | 673 head(EDGES_ELEMENT); |
674 walk_nodes(node, (void *)1); | |
675 tail(EDGES_ELEMENT); | |
676 if (C->cfg() != NULL) { | |
677 head(CONTROL_FLOW_ELEMENT); | |
678 for (uint i = 0; i < C->cfg()->_blocks.size(); i++) { | |
679 Block *b = C->cfg()->_blocks[i]; | |
680 begin_head(BLOCK_ELEMENT); | |
681 print_attr(BLOCK_NAME_PROPERTY, b->_pre_order); | |
682 end_head(); | |
0 | 683 |
222 | 684 head(SUCCESSORS_ELEMENT); |
685 for (uint s = 0; s < C->cfg()->_blocks[i]->_num_succs; s++) { | |
686 begin_elem(SUCCESSOR_ELEMENT); | |
687 print_attr(BLOCK_NAME_PROPERTY, b->_succs[s]->_pre_order); | |
688 end_elem(); | |
0 | 689 } |
222 | 690 tail(SUCCESSORS_ELEMENT); |
0 | 691 |
222 | 692 tail(BLOCK_ELEMENT); |
693 } | |
0 | 694 |
222 | 695 tail(CONTROL_FLOW_ELEMENT); |
0 | 696 } |
222 | 697 tail(GRAPH_ELEMENT); |
698 output()->flush(); | |
0 | 699 } |
700 | |
701 extern const char *NodeClassNames[]; | |
702 | |
703 outputStream *IdealGraphPrinter::output() { | |
222 | 704 return _xml; |
0 | 705 } |
706 | |
707 #endif |