1 | /* |
2 | * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. |
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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | #include "c1/c1_InstructionPrinter.hpp" |
27 | #include "c1/c1_ValueStack.hpp" |
28 | #include "ci/ciArray.hpp" |
29 | #include "ci/ciInstance.hpp" |
30 | #include "ci/ciObject.hpp" |
31 | |
32 | |
33 | #ifndef PRODUCT |
34 | |
35 | const char* InstructionPrinter::basic_type_name(BasicType type) { |
36 | switch (type) { |
37 | case T_BOOLEAN: return "boolean" ; |
38 | case T_BYTE : return "byte" ; |
39 | case T_CHAR : return "char" ; |
40 | case T_SHORT : return "short" ; |
41 | case T_INT : return "int" ; |
42 | case T_LONG : return "long" ; |
43 | case T_FLOAT : return "float" ; |
44 | case T_DOUBLE : return "double" ; |
45 | case T_ARRAY : return "array" ; |
46 | case T_OBJECT : return "object" ; |
47 | default : return "???" ; |
48 | } |
49 | } |
50 | |
51 | |
52 | const char* InstructionPrinter::cond_name(If::Condition cond) { |
53 | switch (cond) { |
54 | case If::eql: return "==" ; |
55 | case If::neq: return "!=" ; |
56 | case If::lss: return "<" ; |
57 | case If::leq: return "<=" ; |
58 | case If::gtr: return ">" ; |
59 | case If::geq: return ">=" ; |
60 | case If::aeq: return "|>=|" ; |
61 | case If::beq: return "|<=|" ; |
62 | default: |
63 | ShouldNotReachHere(); |
64 | return NULL; |
65 | } |
66 | } |
67 | |
68 | |
69 | const char* InstructionPrinter::op_name(Bytecodes::Code op) { |
70 | switch (op) { |
71 | // arithmetic ops |
72 | case Bytecodes::_iadd : // fall through |
73 | case Bytecodes::_ladd : // fall through |
74 | case Bytecodes::_fadd : // fall through |
75 | case Bytecodes::_dadd : return "+" ; |
76 | case Bytecodes::_isub : // fall through |
77 | case Bytecodes::_lsub : // fall through |
78 | case Bytecodes::_fsub : // fall through |
79 | case Bytecodes::_dsub : return "-" ; |
80 | case Bytecodes::_imul : // fall through |
81 | case Bytecodes::_lmul : // fall through |
82 | case Bytecodes::_fmul : // fall through |
83 | case Bytecodes::_dmul : return "*" ; |
84 | case Bytecodes::_idiv : // fall through |
85 | case Bytecodes::_ldiv : // fall through |
86 | case Bytecodes::_fdiv : // fall through |
87 | case Bytecodes::_ddiv : return "/" ; |
88 | case Bytecodes::_irem : // fall through |
89 | case Bytecodes::_lrem : // fall through |
90 | case Bytecodes::_frem : // fall through |
91 | case Bytecodes::_drem : return "%" ; |
92 | // shift ops |
93 | case Bytecodes::_ishl : // fall through |
94 | case Bytecodes::_lshl : return "<<" ; |
95 | case Bytecodes::_ishr : // fall through |
96 | case Bytecodes::_lshr : return ">>" ; |
97 | case Bytecodes::_iushr: // fall through |
98 | case Bytecodes::_lushr: return ">>>" ; |
99 | // logic ops |
100 | case Bytecodes::_iand : // fall through |
101 | case Bytecodes::_land : return "&" ; |
102 | case Bytecodes::_ior : // fall through |
103 | case Bytecodes::_lor : return "|" ; |
104 | case Bytecodes::_ixor : // fall through |
105 | case Bytecodes::_lxor : return "^" ; |
106 | default : return Bytecodes::name(op); |
107 | } |
108 | } |
109 | |
110 | |
111 | bool InstructionPrinter::is_illegal_phi(Value v) { |
112 | Phi* phi = v ? v->as_Phi() : NULL; |
113 | if (phi && phi->is_illegal()) { |
114 | return true; |
115 | } |
116 | return false; |
117 | } |
118 | |
119 | |
120 | bool InstructionPrinter::is_phi_of_block(Value v, BlockBegin* b) { |
121 | Phi* phi = v ? v->as_Phi() : NULL; |
122 | return phi && phi->block() == b; |
123 | } |
124 | |
125 | |
126 | void InstructionPrinter::print_klass(ciKlass* klass) { |
127 | klass->name()->print_symbol_on(output()); |
128 | } |
129 | |
130 | |
131 | void InstructionPrinter::print_object(Value obj) { |
132 | ValueType* type = obj->type(); |
133 | if (type->as_ObjectConstant() != NULL) { |
134 | ciObject* value = type->as_ObjectConstant()->value(); |
135 | if (value->is_null_object()) { |
136 | output()->print("null" ); |
137 | } else if (!value->is_loaded()) { |
138 | output()->print("<unloaded object " INTPTR_FORMAT ">" , p2i(value)); |
139 | } else { |
140 | output()->print("<object " INTPTR_FORMAT " klass=" , p2i(value->constant_encoding())); |
141 | print_klass(value->klass()); |
142 | output()->print(">" ); |
143 | } |
144 | } else if (type->as_InstanceConstant() != NULL) { |
145 | ciInstance* value = type->as_InstanceConstant()->value(); |
146 | if (value->is_loaded()) { |
147 | output()->print("<instance " INTPTR_FORMAT " klass=" , p2i(value->constant_encoding())); |
148 | print_klass(value->klass()); |
149 | output()->print(">" ); |
150 | } else { |
151 | output()->print("<unloaded instance " INTPTR_FORMAT ">" , p2i(value)); |
152 | } |
153 | } else if (type->as_ArrayConstant() != NULL) { |
154 | output()->print("<array " INTPTR_FORMAT ">" , p2i(type->as_ArrayConstant()->value()->constant_encoding())); |
155 | } else if (type->as_ClassConstant() != NULL) { |
156 | ciInstanceKlass* klass = type->as_ClassConstant()->value(); |
157 | if (!klass->is_loaded()) { |
158 | output()->print("<unloaded> " ); |
159 | } |
160 | output()->print("class " ); |
161 | print_klass(klass); |
162 | } else if (type->as_MethodConstant() != NULL) { |
163 | ciMethod* m = type->as_MethodConstant()->value(); |
164 | output()->print("<method %s.%s>" , m->holder()->name()->as_utf8(), m->name()->as_utf8()); |
165 | } else { |
166 | output()->print("???" ); |
167 | } |
168 | } |
169 | |
170 | |
171 | void InstructionPrinter::print_temp(Value value) { |
172 | output()->print("%c%d" , value->type()->tchar(), value->id()); |
173 | } |
174 | |
175 | |
176 | void InstructionPrinter::print_field(AccessField* field) { |
177 | print_value(field->obj()); |
178 | output()->print("._%d" , field->offset()); |
179 | } |
180 | |
181 | |
182 | void InstructionPrinter::print_indexed(AccessIndexed* indexed) { |
183 | print_value(indexed->array()); |
184 | output()->put('['); |
185 | print_value(indexed->index()); |
186 | output()->put(']'); |
187 | if (indexed->length() != NULL) { |
188 | output()->put('('); |
189 | print_value(indexed->length()); |
190 | output()->put(')'); |
191 | } |
192 | } |
193 | |
194 | |
195 | void InstructionPrinter::print_monitor(AccessMonitor* monitor) { |
196 | output()->print("monitor[%d](" , monitor->monitor_no()); |
197 | print_value(monitor->obj()); |
198 | output()->put(')'); |
199 | } |
200 | |
201 | |
202 | void InstructionPrinter::print_op2(Op2* instr) { |
203 | print_value(instr->x()); |
204 | output()->print(" %s " , op_name(instr->op())); |
205 | print_value(instr->y()); |
206 | } |
207 | |
208 | |
209 | void InstructionPrinter::print_value(Value value) { |
210 | if (value == NULL) { |
211 | output()->print("NULL" ); |
212 | } else { |
213 | print_temp(value); |
214 | } |
215 | } |
216 | |
217 | |
218 | void InstructionPrinter::print_instr(Instruction* instr) { |
219 | instr->visit(this); |
220 | } |
221 | |
222 | |
223 | void InstructionPrinter::print_stack(ValueStack* stack) { |
224 | int start_position = output()->position(); |
225 | if (stack->stack_is_empty()) { |
226 | output()->print("empty stack" ); |
227 | } else { |
228 | output()->print("stack [" ); |
229 | for (int i = 0; i < stack->stack_size();) { |
230 | if (i > 0) output()->print(", " ); |
231 | output()->print("%d:" , i); |
232 | Value value = stack->stack_at_inc(i); |
233 | print_value(value); |
234 | Phi* phi = value->as_Phi(); |
235 | if (phi != NULL) { |
236 | if (phi->operand()->is_valid()) { |
237 | output()->print(" " ); |
238 | phi->operand()->print(output()); |
239 | } |
240 | } |
241 | } |
242 | output()->put(']'); |
243 | } |
244 | if (!stack->no_active_locks()) { |
245 | // print out the lines on the line below this |
246 | // one at the same indentation level. |
247 | output()->cr(); |
248 | fill_to(start_position, ' '); |
249 | output()->print("locks [" ); |
250 | for (int i = i = 0; i < stack->locks_size(); i++) { |
251 | Value t = stack->lock_at(i); |
252 | if (i > 0) output()->print(", " ); |
253 | output()->print("%d:" , i); |
254 | if (t == NULL) { |
255 | // synchronized methods push null on the lock stack |
256 | output()->print("this" ); |
257 | } else { |
258 | print_value(t); |
259 | } |
260 | } |
261 | output()->print("]" ); |
262 | } |
263 | } |
264 | |
265 | |
266 | void InstructionPrinter::print_inline_level(BlockBegin* block) { |
267 | output()->print_cr("inlining depth %d" , block->scope()->level()); |
268 | } |
269 | |
270 | |
271 | void InstructionPrinter::print_unsafe_op(UnsafeOp* op, const char* name) { |
272 | output()->print("%s" , name); |
273 | output()->print(".(" ); |
274 | } |
275 | |
276 | void InstructionPrinter::print_unsafe_raw_op(UnsafeRawOp* op, const char* name) { |
277 | print_unsafe_op(op, name); |
278 | output()->print("base " ); |
279 | print_value(op->base()); |
280 | if (op->has_index()) { |
281 | output()->print(", index " ); print_value(op->index()); |
282 | output()->print(", log2_scale %d" , op->log2_scale()); |
283 | } |
284 | } |
285 | |
286 | |
287 | void InstructionPrinter::print_unsafe_object_op(UnsafeObjectOp* op, const char* name) { |
288 | print_unsafe_op(op, name); |
289 | print_value(op->object()); |
290 | output()->print(", " ); |
291 | print_value(op->offset()); |
292 | } |
293 | |
294 | |
295 | void InstructionPrinter::print_phi(int i, Value v, BlockBegin* b) { |
296 | Phi* phi = v->as_Phi(); |
297 | output()->print("%2d " , i); |
298 | print_value(v); |
299 | // print phi operands |
300 | if (phi && phi->block() == b) { |
301 | output()->print(" [" ); |
302 | for (int j = 0; j < phi->operand_count(); j ++) { |
303 | output()->print(" " ); |
304 | Value opd = phi->operand_at(j); |
305 | if (opd) print_value(opd); |
306 | else output()->print("NULL" ); |
307 | } |
308 | output()->print("] " ); |
309 | } |
310 | print_alias(v); |
311 | } |
312 | |
313 | |
314 | void InstructionPrinter::print_alias(Value v) { |
315 | if (v != v->subst()) { |
316 | output()->print("alias " ); print_value(v->subst()); |
317 | } |
318 | } |
319 | |
320 | |
321 | void InstructionPrinter::fill_to(int pos, char filler) { |
322 | while (output()->position() < pos) output()->put(filler); |
323 | } |
324 | |
325 | |
326 | void InstructionPrinter::print_head() { |
327 | const char filler = '_'; |
328 | fill_to(bci_pos , filler); output()->print("bci" ); |
329 | fill_to(use_pos , filler); output()->print("use" ); |
330 | fill_to(temp_pos , filler); output()->print("tid" ); |
331 | fill_to(instr_pos, filler); output()->print("instr" ); |
332 | fill_to(end_pos , filler); |
333 | output()->cr(); |
334 | } |
335 | |
336 | |
337 | void InstructionPrinter::print_line(Instruction* instr) { |
338 | // print instruction data on one line |
339 | if (instr->is_pinned()) output()->put('.'); |
340 | fill_to(bci_pos ); output()->print("%d" , instr->printable_bci()); |
341 | fill_to(use_pos ); output()->print("%d" , instr->use_count()); |
342 | fill_to(temp_pos ); print_temp(instr); |
343 | fill_to(instr_pos); print_instr(instr); |
344 | output()->cr(); |
345 | // add a line for StateSplit instructions w/ non-empty stacks |
346 | // (make it robust so we can print incomplete instructions) |
347 | StateSplit* split = instr->as_StateSplit(); |
348 | if (split != NULL && split->state() != NULL && !split->state()->stack_is_empty()) { |
349 | fill_to(instr_pos); print_stack(split->state()); |
350 | output()->cr(); |
351 | } |
352 | } |
353 | |
354 | |
355 | void InstructionPrinter::do_Phi(Phi* x) { |
356 | output()->print("phi function" ); // make that more detailed later |
357 | if (x->is_illegal()) |
358 | output()->print(" (illegal)" ); |
359 | } |
360 | |
361 | |
362 | void InstructionPrinter::do_Local(Local* x) { |
363 | output()->print("local[index %d]" , x->java_index()); |
364 | } |
365 | |
366 | |
367 | void InstructionPrinter::do_Constant(Constant* x) { |
368 | ValueType* t = x->type(); |
369 | switch (t->tag()) { |
370 | case intTag : output()->print("%d" , t->as_IntConstant ()->value()); break; |
371 | case longTag : output()->print(JLONG_FORMAT, t->as_LongConstant()->value()); output()->print("L" ); break; |
372 | case floatTag : output()->print("%g" , t->as_FloatConstant ()->value()); break; |
373 | case doubleTag : output()->print("%gD" , t->as_DoubleConstant()->value()); break; |
374 | case objectTag : print_object(x); break; |
375 | case addressTag: output()->print("bci:%d" , t->as_AddressConstant()->value()); break; |
376 | default : output()->print("???" ); break; |
377 | } |
378 | } |
379 | |
380 | |
381 | void InstructionPrinter::do_LoadField(LoadField* x) { |
382 | print_field(x); |
383 | output()->print(" (%c)" , type2char(x->field()->type()->basic_type())); |
384 | output()->print(" %s" , x->field()->name()->as_utf8()); |
385 | } |
386 | |
387 | |
388 | void InstructionPrinter::do_StoreField(StoreField* x) { |
389 | print_field(x); |
390 | output()->print(" := " ); |
391 | print_value(x->value()); |
392 | output()->print(" (%c)" , type2char(x->field()->type()->basic_type())); |
393 | output()->print(" %s" , x->field()->name()->as_utf8()); |
394 | } |
395 | |
396 | |
397 | void InstructionPrinter::do_ArrayLength(ArrayLength* x) { |
398 | print_value(x->array()); |
399 | output()->print(".length" ); |
400 | } |
401 | |
402 | |
403 | void InstructionPrinter::do_LoadIndexed(LoadIndexed* x) { |
404 | print_indexed(x); |
405 | output()->print(" (%c)" , type2char(x->elt_type())); |
406 | if (x->check_flag(Instruction::NeedsRangeCheckFlag)) { |
407 | output()->print(" [rc]" ); |
408 | } |
409 | } |
410 | |
411 | |
412 | void InstructionPrinter::do_StoreIndexed(StoreIndexed* x) { |
413 | print_indexed(x); |
414 | output()->print(" := " ); |
415 | print_value(x->value()); |
416 | output()->print(" (%c)" , type2char(x->elt_type())); |
417 | if (x->check_flag(Instruction::NeedsRangeCheckFlag)) { |
418 | output()->print(" [rc]" ); |
419 | } |
420 | } |
421 | |
422 | void InstructionPrinter::do_NegateOp(NegateOp* x) { |
423 | output()->put('-'); |
424 | print_value(x->x()); |
425 | } |
426 | |
427 | |
428 | void InstructionPrinter::do_ArithmeticOp(ArithmeticOp* x) { |
429 | print_op2(x); |
430 | } |
431 | |
432 | |
433 | void InstructionPrinter::do_ShiftOp(ShiftOp* x) { |
434 | print_op2(x); |
435 | } |
436 | |
437 | |
438 | void InstructionPrinter::do_LogicOp(LogicOp* x) { |
439 | print_op2(x); |
440 | } |
441 | |
442 | |
443 | void InstructionPrinter::do_CompareOp(CompareOp* x) { |
444 | print_op2(x); |
445 | } |
446 | |
447 | |
448 | void InstructionPrinter::do_IfOp(IfOp* x) { |
449 | print_value(x->x()); |
450 | output()->print(" %s " , cond_name(x->cond())); |
451 | print_value(x->y()); |
452 | output()->print(" ? " ); |
453 | print_value(x->tval()); |
454 | output()->print(" : " ); |
455 | print_value(x->fval()); |
456 | } |
457 | |
458 | |
459 | void InstructionPrinter::do_Convert(Convert* x) { |
460 | output()->print("%s(" , Bytecodes::name(x->op())); |
461 | print_value(x->value()); |
462 | output()->put(')'); |
463 | } |
464 | |
465 | |
466 | void InstructionPrinter::do_NullCheck(NullCheck* x) { |
467 | output()->print("null_check(" ); |
468 | print_value(x->obj()); |
469 | output()->put(')'); |
470 | if (!x->can_trap()) { |
471 | output()->print(" (eliminated)" ); |
472 | } |
473 | } |
474 | |
475 | |
476 | void InstructionPrinter::do_TypeCast(TypeCast* x) { |
477 | output()->print("type_cast(" ); |
478 | print_value(x->obj()); |
479 | output()->print(") " ); |
480 | if (x->declared_type()->is_klass()) |
481 | print_klass(x->declared_type()->as_klass()); |
482 | else |
483 | output()->print("%s" , type2name(x->declared_type()->basic_type())); |
484 | } |
485 | |
486 | |
487 | void InstructionPrinter::do_Invoke(Invoke* x) { |
488 | if (x->receiver() != NULL) { |
489 | print_value(x->receiver()); |
490 | output()->print("." ); |
491 | } |
492 | |
493 | output()->print("%s(" , Bytecodes::name(x->code())); |
494 | for (int i = 0; i < x->number_of_arguments(); i++) { |
495 | if (i > 0) output()->print(", " ); |
496 | print_value(x->argument_at(i)); |
497 | } |
498 | output()->print_cr(")" ); |
499 | fill_to(instr_pos); |
500 | output()->print("%s.%s%s" , |
501 | x->target()->holder()->name()->as_utf8(), |
502 | x->target()->name()->as_utf8(), |
503 | x->target()->signature()->as_symbol()->as_utf8()); |
504 | } |
505 | |
506 | |
507 | void InstructionPrinter::do_NewInstance(NewInstance* x) { |
508 | output()->print("new instance " ); |
509 | print_klass(x->klass()); |
510 | } |
511 | |
512 | |
513 | void InstructionPrinter::do_NewTypeArray(NewTypeArray* x) { |
514 | output()->print("new %s array [" , basic_type_name(x->elt_type())); |
515 | print_value(x->length()); |
516 | output()->put(']'); |
517 | } |
518 | |
519 | |
520 | void InstructionPrinter::do_NewObjectArray(NewObjectArray* x) { |
521 | output()->print("new object array [" ); |
522 | print_value(x->length()); |
523 | output()->print("] " ); |
524 | print_klass(x->klass()); |
525 | } |
526 | |
527 | |
528 | void InstructionPrinter::do_NewMultiArray(NewMultiArray* x) { |
529 | output()->print("new multi array [" ); |
530 | Values* dims = x->dims(); |
531 | for (int i = 0; i < dims->length(); i++) { |
532 | if (i > 0) output()->print(", " ); |
533 | print_value(dims->at(i)); |
534 | } |
535 | output()->print("] " ); |
536 | print_klass(x->klass()); |
537 | } |
538 | |
539 | |
540 | void InstructionPrinter::do_MonitorEnter(MonitorEnter* x) { |
541 | output()->print("enter " ); |
542 | print_monitor(x); |
543 | } |
544 | |
545 | |
546 | void InstructionPrinter::do_MonitorExit(MonitorExit* x) { |
547 | output()->print("exit " ); |
548 | print_monitor(x); |
549 | } |
550 | |
551 | |
552 | void InstructionPrinter::do_Intrinsic(Intrinsic* x) { |
553 | const char* name = vmIntrinsics::name_at(x->id()); |
554 | if (name[0] == '_') name++; // strip leading bug from _hashCode, etc. |
555 | const char* kname = vmSymbols::name_for(vmIntrinsics::class_for(x->id())); |
556 | if (strchr(name, '_') == NULL) { |
557 | kname = NULL; |
558 | } else { |
559 | const char* kptr = strrchr(kname, '/'); |
560 | if (kptr != NULL) kname = kptr + 1; |
561 | } |
562 | if (kname == NULL) |
563 | output()->print("%s(" , name); |
564 | else |
565 | output()->print("%s.%s(" , kname, name); |
566 | for (int i = 0; i < x->number_of_arguments(); i++) { |
567 | if (i > 0) output()->print(", " ); |
568 | print_value(x->argument_at(i)); |
569 | } |
570 | output()->put(')'); |
571 | } |
572 | |
573 | |
574 | void InstructionPrinter::do_BlockBegin(BlockBegin* x) { |
575 | // print block id |
576 | BlockEnd* end = x->end(); |
577 | output()->print("B%d " , x->block_id()); |
578 | |
579 | // print flags |
580 | bool printed_flag = false; |
581 | if (x->is_set(BlockBegin::std_entry_flag)) { |
582 | if (!printed_flag) output()->print("(" ); |
583 | output()->print("S" ); printed_flag = true; |
584 | } |
585 | if (x->is_set(BlockBegin::osr_entry_flag)) { |
586 | if (!printed_flag) output()->print("(" ); |
587 | output()->print("O" ); printed_flag = true; |
588 | } |
589 | if (x->is_set(BlockBegin::exception_entry_flag)) { |
590 | if (!printed_flag) output()->print("(" ); |
591 | output()->print("E" ); printed_flag = true; |
592 | } |
593 | if (x->is_set(BlockBegin::subroutine_entry_flag)) { |
594 | if (!printed_flag) output()->print("(" ); |
595 | output()->print("s" ); printed_flag = true; |
596 | } |
597 | if (x->is_set(BlockBegin::parser_loop_header_flag)) { |
598 | if (!printed_flag) output()->print("(" ); |
599 | output()->print("LH" ); printed_flag = true; |
600 | } |
601 | if (x->is_set(BlockBegin::backward_branch_target_flag)) { |
602 | if (!printed_flag) output()->print("(" ); |
603 | output()->print("b" ); printed_flag = true; |
604 | } |
605 | if (x->is_set(BlockBegin::was_visited_flag)) { |
606 | if (!printed_flag) output()->print("(" ); |
607 | output()->print("V" ); printed_flag = true; |
608 | } |
609 | if (printed_flag) output()->print(") " ); |
610 | |
611 | // print block bci range |
612 | output()->print("[%d, %d]" , x->bci(), (end == NULL ? -1 : end->printable_bci())); |
613 | |
614 | // print block successors |
615 | if (end != NULL && end->number_of_sux() > 0) { |
616 | output()->print(" ->" ); |
617 | for (int i = 0; i < end->number_of_sux(); i++) { |
618 | output()->print(" B%d" , end->sux_at(i)->block_id()); |
619 | } |
620 | } |
621 | // print exception handlers |
622 | if (x->number_of_exception_handlers() > 0) { |
623 | output()->print(" (xhandlers " ); |
624 | for (int i = 0; i < x->number_of_exception_handlers(); i++) { |
625 | if (i > 0) output()->print(" " ); |
626 | output()->print("B%d" , x->exception_handler_at(i)->block_id()); |
627 | } |
628 | output()->put(')'); |
629 | } |
630 | |
631 | // print dominator block |
632 | if (x->dominator() != NULL) { |
633 | output()->print(" dom B%d" , x->dominator()->block_id()); |
634 | } |
635 | |
636 | // print predecessors and successors |
637 | if (x->successors()->length() > 0) { |
638 | output()->print(" sux:" ); |
639 | for (int i = 0; i < x->successors()->length(); i ++) { |
640 | output()->print(" B%d" , x->successors()->at(i)->block_id()); |
641 | } |
642 | } |
643 | |
644 | if (x->number_of_preds() > 0) { |
645 | output()->print(" pred:" ); |
646 | for (int i = 0; i < x->number_of_preds(); i ++) { |
647 | output()->print(" B%d" , x->pred_at(i)->block_id()); |
648 | } |
649 | } |
650 | |
651 | if (!_print_phis) { |
652 | return; |
653 | } |
654 | |
655 | // print phi functions |
656 | bool has_phis_in_locals = false; |
657 | bool has_phis_on_stack = false; |
658 | |
659 | if (x->end() && x->end()->state()) { |
660 | ValueStack* state = x->state(); |
661 | |
662 | int i = 0; |
663 | while (!has_phis_on_stack && i < state->stack_size()) { |
664 | Value v = state->stack_at_inc(i); |
665 | has_phis_on_stack = is_phi_of_block(v, x); |
666 | } |
667 | |
668 | do { |
669 | for (i = 0; !has_phis_in_locals && i < state->locals_size();) { |
670 | Value v = state->local_at(i); |
671 | has_phis_in_locals = is_phi_of_block(v, x); |
672 | // also ignore illegal HiWords |
673 | if (v && !v->type()->is_illegal()) i += v->type()->size(); else i ++; |
674 | } |
675 | state = state->caller_state(); |
676 | } while (state != NULL); |
677 | |
678 | } |
679 | |
680 | // print values in locals |
681 | if (has_phis_in_locals) { |
682 | output()->cr(); output()->print_cr("Locals:" ); |
683 | |
684 | ValueStack* state = x->state(); |
685 | do { |
686 | for (int i = 0; i < state->locals_size();) { |
687 | Value v = state->local_at(i); |
688 | if (v) { |
689 | print_phi(i, v, x); output()->cr(); |
690 | // also ignore illegal HiWords |
691 | i += (v->type()->is_illegal() ? 1 : v->type()->size()); |
692 | } else { |
693 | i ++; |
694 | } |
695 | } |
696 | output()->cr(); |
697 | state = state->caller_state(); |
698 | } while (state != NULL); |
699 | } |
700 | |
701 | // print values on stack |
702 | if (has_phis_on_stack) { |
703 | output()->print_cr("Stack:" ); |
704 | int i = 0; |
705 | while (i < x->state()->stack_size()) { |
706 | int o = i; |
707 | Value v = x->state()->stack_at_inc(i); |
708 | if (v) { |
709 | print_phi(o, v, x); output()->cr(); |
710 | } |
711 | } |
712 | } |
713 | } |
714 | |
715 | |
716 | void InstructionPrinter::do_CheckCast(CheckCast* x) { |
717 | output()->print("checkcast(" ); |
718 | print_value(x->obj()); |
719 | output()->print(") " ); |
720 | print_klass(x->klass()); |
721 | } |
722 | |
723 | |
724 | void InstructionPrinter::do_InstanceOf(InstanceOf* x) { |
725 | output()->print("instanceof(" ); |
726 | print_value(x->obj()); |
727 | output()->print(") " ); |
728 | print_klass(x->klass()); |
729 | } |
730 | |
731 | |
732 | void InstructionPrinter::do_Goto(Goto* x) { |
733 | output()->print("goto B%d" , x->default_sux()->block_id()); |
734 | if (x->is_safepoint()) output()->print(" (safepoint)" ); |
735 | } |
736 | |
737 | |
738 | void InstructionPrinter::do_If(If* x) { |
739 | output()->print("if " ); |
740 | print_value(x->x()); |
741 | output()->print(" %s " , cond_name(x->cond())); |
742 | print_value(x->y()); |
743 | output()->print(" then B%d else B%d" , x->sux_at(0)->block_id(), x->sux_at(1)->block_id()); |
744 | if (x->is_safepoint()) output()->print(" (safepoint)" ); |
745 | } |
746 | |
747 | |
748 | void InstructionPrinter::do_IfInstanceOf(IfInstanceOf* x) { |
749 | output()->print("<IfInstanceOf>" ); |
750 | } |
751 | |
752 | |
753 | void InstructionPrinter::do_TableSwitch(TableSwitch* x) { |
754 | output()->print("tableswitch " ); |
755 | if (x->is_safepoint()) output()->print("(safepoint) " ); |
756 | print_value(x->tag()); |
757 | output()->cr(); |
758 | int l = x->length(); |
759 | for (int i = 0; i < l; i++) { |
760 | fill_to(instr_pos); |
761 | output()->print_cr("case %5d: B%d" , x->lo_key() + i, x->sux_at(i)->block_id()); |
762 | } |
763 | fill_to(instr_pos); |
764 | output()->print("default : B%d" , x->default_sux()->block_id()); |
765 | } |
766 | |
767 | |
768 | void InstructionPrinter::do_LookupSwitch(LookupSwitch* x) { |
769 | output()->print("lookupswitch " ); |
770 | if (x->is_safepoint()) output()->print("(safepoint) " ); |
771 | print_value(x->tag()); |
772 | output()->cr(); |
773 | int l = x->length(); |
774 | for (int i = 0; i < l; i++) { |
775 | fill_to(instr_pos); |
776 | output()->print_cr("case %5d: B%d" , x->key_at(i), x->sux_at(i)->block_id()); |
777 | } |
778 | fill_to(instr_pos); |
779 | output()->print("default : B%d" , x->default_sux()->block_id()); |
780 | } |
781 | |
782 | |
783 | void InstructionPrinter::do_Return(Return* x) { |
784 | if (x->result() == NULL) { |
785 | output()->print("return" ); |
786 | } else { |
787 | output()->print("%creturn " , x->type()->tchar()); |
788 | print_value(x->result()); |
789 | } |
790 | } |
791 | |
792 | |
793 | void InstructionPrinter::do_Throw(Throw* x) { |
794 | output()->print("throw " ); |
795 | print_value(x->exception()); |
796 | } |
797 | |
798 | |
799 | void InstructionPrinter::do_Base(Base* x) { |
800 | output()->print("std entry B%d" , x->std_entry()->block_id()); |
801 | if (x->number_of_sux() > 1) { |
802 | output()->print(" osr entry B%d" , x->osr_entry()->block_id()); |
803 | } |
804 | } |
805 | |
806 | |
807 | void InstructionPrinter::do_OsrEntry(OsrEntry* x) { |
808 | output()->print("osr entry" ); |
809 | } |
810 | |
811 | |
812 | void InstructionPrinter::do_ExceptionObject(ExceptionObject* x) { |
813 | output()->print("incoming exception" ); |
814 | } |
815 | |
816 | |
817 | void InstructionPrinter::do_RoundFP(RoundFP* x) { |
818 | output()->print("round_fp " ); |
819 | print_value(x->input()); |
820 | } |
821 | |
822 | |
823 | void InstructionPrinter::do_UnsafeGetRaw(UnsafeGetRaw* x) { |
824 | print_unsafe_raw_op(x, "UnsafeGetRaw" ); |
825 | output()->put(')'); |
826 | } |
827 | |
828 | |
829 | void InstructionPrinter::do_UnsafePutRaw(UnsafePutRaw* x) { |
830 | print_unsafe_raw_op(x, "UnsafePutRaw" ); |
831 | output()->print(", value " ); |
832 | print_value(x->value()); |
833 | output()->put(')'); |
834 | } |
835 | |
836 | |
837 | void InstructionPrinter::do_UnsafeGetObject(UnsafeGetObject* x) { |
838 | print_unsafe_object_op(x, "UnsafeGetObject" ); |
839 | output()->put(')'); |
840 | } |
841 | |
842 | |
843 | void InstructionPrinter::do_UnsafePutObject(UnsafePutObject* x) { |
844 | print_unsafe_object_op(x, "UnsafePutObject" ); |
845 | output()->print(", value " ); |
846 | print_value(x->value()); |
847 | output()->put(')'); |
848 | } |
849 | |
850 | void InstructionPrinter::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { |
851 | print_unsafe_object_op(x, x->is_add()?"UnsafeGetAndSetObject (add)" :"UnsafeGetAndSetObject" ); |
852 | output()->print(", value " ); |
853 | print_value(x->value()); |
854 | output()->put(')'); |
855 | } |
856 | |
857 | void InstructionPrinter::do_RangeCheckPredicate(RangeCheckPredicate* x) { |
858 | |
859 | if (x->x() != NULL && x->y() != NULL) { |
860 | output()->print("if " ); |
861 | print_value(x->x()); |
862 | output()->print(" %s " , cond_name(x->cond())); |
863 | print_value(x->y()); |
864 | output()->print(" then deoptimize!" ); |
865 | } else { |
866 | output()->print("always deoptimize!" ); |
867 | } |
868 | } |
869 | |
870 | #ifdef ASSERT |
871 | void InstructionPrinter::do_Assert(Assert* x) { |
872 | output()->print("assert " ); |
873 | print_value(x->x()); |
874 | output()->print(" %s " , cond_name(x->cond())); |
875 | print_value(x->y()); |
876 | } |
877 | #endif |
878 | |
879 | void InstructionPrinter::do_ProfileCall(ProfileCall* x) { |
880 | output()->print("profile " ); |
881 | print_value(x->recv()); |
882 | output()->print(" %s.%s" , x->method()->holder()->name()->as_utf8(), x->method()->name()->as_utf8()); |
883 | if (x->known_holder() != NULL) { |
884 | output()->print(", " ); |
885 | print_klass(x->known_holder()); |
886 | output()->print(" " ); |
887 | } |
888 | for (int i = 0; i < x->nb_profiled_args(); i++) { |
889 | if (i > 0) output()->print(", " ); |
890 | print_value(x->profiled_arg_at(i)); |
891 | if (x->arg_needs_null_check(i)) { |
892 | output()->print(" [NC]" ); |
893 | } |
894 | } |
895 | output()->put(')'); |
896 | } |
897 | |
898 | void InstructionPrinter::do_ProfileReturnType(ProfileReturnType* x) { |
899 | output()->print("profile ret type " ); |
900 | print_value(x->ret()); |
901 | output()->print(" %s.%s" , x->method()->holder()->name()->as_utf8(), x->method()->name()->as_utf8()); |
902 | output()->put(')'); |
903 | } |
904 | void InstructionPrinter::do_ProfileInvoke(ProfileInvoke* x) { |
905 | output()->print("profile_invoke " ); |
906 | output()->print(" %s.%s" , x->inlinee()->holder()->name()->as_utf8(), x->inlinee()->name()->as_utf8()); |
907 | output()->put(')'); |
908 | |
909 | } |
910 | |
911 | void InstructionPrinter::do_RuntimeCall(RuntimeCall* x) { |
912 | output()->print("call_rt %s(" , x->entry_name()); |
913 | for (int i = 0; i < x->number_of_arguments(); i++) { |
914 | if (i > 0) output()->print(", " ); |
915 | print_value(x->argument_at(i)); |
916 | } |
917 | output()->put(')'); |
918 | } |
919 | |
920 | void InstructionPrinter::do_MemBar(MemBar* x) { |
921 | LIR_Code code = x->code(); |
922 | switch (code) { |
923 | case lir_membar_acquire : output()->print("membar_acquire" ); break; |
924 | case lir_membar_release : output()->print("membar_release" ); break; |
925 | case lir_membar : output()->print("membar" ); break; |
926 | case lir_membar_loadload : output()->print("membar_loadload" ); break; |
927 | case lir_membar_storestore: output()->print("membar_storestore" ); break; |
928 | case lir_membar_loadstore : output()->print("membar_loadstore" ); break; |
929 | case lir_membar_storeload : output()->print("membar_storeload" ); break; |
930 | default : ShouldNotReachHere(); break; |
931 | } |
932 | } |
933 | |
934 | #endif // PRODUCT |
935 | |