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