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