1 /*
2 * Copyright (c) 1997, 2026, 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 "classfile/classPrinter.hpp"
26 #include "classfile/javaClasses.inline.hpp"
27 #include "interpreter/bytecodeHistogram.hpp"
28 #include "interpreter/bytecodes.hpp"
29 #include "interpreter/bytecodeStream.hpp"
30 #include "interpreter/bytecodeTracer.hpp"
31 #include "interpreter/interpreter.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "oops/constantPool.inline.hpp"
34 #include "oops/method.hpp"
35 #include "oops/methodData.hpp"
36 #include "runtime/atomicAccess.hpp"
37 #include "runtime/handles.inline.hpp"
38 #include "runtime/mutexLocker.hpp"
39 #include "runtime/osThread.hpp"
40 #include "utilities/align.hpp"
41
42 // Prints the current bytecode and its attributes using bytecode-specific information.
43
44 class BytecodePrinter {
45 private:
46 // %%% This field is not GC-ed, and so can contain garbage
47 // between critical sections. Use only pointer-comparison
48 // operations on the pointer, except within a critical section.
49 // (Also, ensure that occasional false positives are benign.)
50 Method* _current_method;
51 bool _is_wide;
52 Bytecodes::Code _code;
53 address _next_pc; // current decoding position
54 int _flags;
55 bool _is_linked;
56
57 bool is_linked() const { return _is_linked; }
58 void align() { _next_pc = align_up(_next_pc, sizeof(jint)); }
59 int get_byte() { return *(jbyte*) _next_pc++; } // signed
60 int get_index_u1() { return *(address)_next_pc++; } // returns 0x00 - 0xff as an int
61 short get_short() { short i = Bytes::get_Java_u2 (_next_pc); _next_pc += 2; return i; }
62 int get_int() { int i = Bytes::get_Java_u4 (_next_pc); _next_pc += 4; return i; }
63 int get_native_index_u2() { int i = Bytes::get_native_u2(_next_pc); _next_pc += 2; return i; }
64 int get_native_index_u4() { int i = Bytes::get_native_u4(_next_pc); _next_pc += 4; return i; }
65 int get_Java_index_u2() { int i = Bytes::get_Java_u2 (_next_pc); _next_pc += 2; return i; }
66 int get_Java_index_u4() { int i = Bytes::get_Java_u4 (_next_pc); _next_pc += 4; return i; }
67 int get_index_special() { return (is_wide()) ? get_Java_index_u2() : get_index_u1(); }
68 Method* method() const { return _current_method; }
69 bool is_wide() const { return _is_wide; }
70 Bytecodes::Code raw_code() const { return Bytecodes::Code(_code); }
71 ConstantPool* constants() const { return method()->constants(); }
72 ConstantPoolCache* cpcache() const { assert(is_linked(), "must be"); return constants()->cache(); }
73
74 void print_constant(int i, outputStream* st);
75 void print_cpcache_entry(int cpc_index, outputStream* st);
76 void print_invokedynamic(int indy_index, int cp_index, outputStream* st);
77 void print_bsm(int cp_index, outputStream* st);
78 void print_field_or_method(int cp_index, outputStream* st);
79 void print_dynamic(int cp_index, outputStream* st);
80 void print_attributes(int bci, outputStream* st);
81 void bytecode_epilog(int bci, outputStream* st);
82
83 public:
84 BytecodePrinter(int flags = 0) : _is_wide(false), _code(Bytecodes::_illegal), _flags(flags) {}
85
86 #ifndef PRODUCT
87 BytecodePrinter(Method* prev_method) : BytecodePrinter(0) {
88 _current_method = prev_method;
89 }
90
91 // This method is called while executing the raw bytecodes, so none of
92 // the adjustments that BytecodeStream performs applies.
93 void trace(const methodHandle& method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
94 ResourceMark rm;
95 bool method_changed = _current_method != method();
96 _current_method = method();
97 _is_linked = method->method_holder()->is_linked();
98 assert(_is_linked, "this function must be called on methods that are already executing");
99
100 if (method_changed) {
101 // Note 1: This code will not work as expected with true MT/MP.
102 // Need an explicit lock or a different solution.
103 // It is possible for this block to be skipped, if a garbage
104 // _current_method pointer happens to have the same bits as
105 // the incoming method. We could lose a line of trace output.
106 // This is acceptable in a debug-only feature.
107 st->cr();
108 st->print("[%zu] ", Thread::current()->osthread()->thread_id_for_printing());
109 method->print_name(st);
110 st->cr();
111 }
112 Bytecodes::Code code;
113 if (is_wide()) {
114 // bcp wasn't advanced if previous bytecode was _wide.
115 code = Bytecodes::code_at(method(), bcp+1);
116 } else {
117 code = Bytecodes::code_at(method(), bcp);
118 }
119 _code = code;
120 _next_pc = is_wide() ? bcp+2 : bcp+1;
121 // Trace each bytecode unless we're truncating the tracing output, then only print the first
122 // bytecode in every method as well as returns/throws that pop control flow
123 if (!TraceBytecodesTruncated || method_changed ||
124 code == Bytecodes::_athrow ||
125 code == Bytecodes::_return_register_finalizer ||
126 (code >= Bytecodes::_ireturn && code <= Bytecodes::_return)) {
127 int bci = (int)(bcp - method->code_base());
128 st->print("[%zu] ", Thread::current()->osthread()->thread_id_for_printing());
129 if (Verbose) {
130 st->print("%8zu %4d " INTPTR_FORMAT " " INTPTR_FORMAT " %s",
131 BytecodeCounter::counter_value(), bci, tos, tos2, Bytecodes::name(code));
132 } else {
133 st->print("%8zu %4d %s",
134 BytecodeCounter::counter_value(), bci, Bytecodes::name(code));
135 }
136 print_attributes(bci, st);
137 }
138 // Set is_wide for the next one, since the caller of this doesn't skip
139 // the next bytecode.
140 _is_wide = (code == Bytecodes::_wide);
141 _code = Bytecodes::_illegal;
142
143 if (TraceBytecodesStopAt != 0 && BytecodeCounter::counter_value() >= TraceBytecodesStopAt) {
144 TraceBytecodes = false;
145 }
146 }
147 #endif
148
149 // Used for Method::print_codes(). The input bcp comes from
150 // BytecodeStream, which will skip wide bytecodes.
151 void trace(const methodHandle& method, address bcp, outputStream* st) {
152 _current_method = method();
153 _is_linked = method->method_holder()->is_linked();
154 ResourceMark rm;
155 Bytecodes::Code code = Bytecodes::code_at(method(), bcp);
156 // Set is_wide
157 _is_wide = (code == Bytecodes::_wide);
158 if (is_wide()) {
159 code = Bytecodes::code_at(method(), bcp+1);
160 }
161 _code = code;
162 int bci = (int)(bcp - method->code_base());
163 // Print bytecode index and name
164 if (ClassPrinter::has_mode(_flags, ClassPrinter::PRINT_BYTECODE_ADDR)) {
165 st->print(INTPTR_FORMAT " ", p2i(bcp));
166 }
167 if (is_wide()) {
168 st->print("%4d %s_w", bci, Bytecodes::name(code));
169 } else {
170 st->print("%4d %s", bci, Bytecodes::name(code));
171 }
172 _next_pc = is_wide() ? bcp+2 : bcp+1;
173 print_attributes(bci, st);
174 bytecode_epilog(bci, st);
175 }
176 };
177
178 #ifndef PRODUCT
179 // We need a global instance to keep track of the method being printed so we can report that
180 // the method has changed. If this method is redefined and removed, that's ok because the method passed
181 // in won't match, and this will print the method passed in again. Racing threads changing this global
182 // will result in reprinting the method passed in again.
183 static Method* _method_currently_being_printed = nullptr;
184
185 void BytecodeTracer::trace_interpreter(const methodHandle& method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
186 if (TraceBytecodes && BytecodeCounter::counter_value() >= TraceBytecodesAt) {
187 BytecodePrinter printer(AtomicAccess::load_acquire(&_method_currently_being_printed));
188 printer.trace(method, bcp, tos, tos2, st);
189 // Save method currently being printed to detect when method printing changes.
190 AtomicAccess::release_store(&_method_currently_being_printed, method());
191 }
192 }
193 #endif
194
195 void BytecodeTracer::print_method_codes(const methodHandle& method, int from, int to, outputStream* st, int flags, bool buffered) {
196 BytecodePrinter method_printer(flags);
197 BytecodeStream s(method);
198 s.set_interval(from, to);
199
200 ResourceMark rm;
201 stringStream ss;
202 outputStream* out = buffered ? &ss : st;
203 while (s.next() >= 0) {
204 method_printer.trace(method, s.bcp(), out);
205 }
206 if (buffered) {
207 st->print("%s", ss.as_string());
208 }
209 }
210
211 void BytecodePrinter::print_constant(int cp_index, outputStream* st) {
212 ConstantPool* constants = method()->constants();
213 constantTag tag = constants->tag_at(cp_index);
214
215 if (tag.is_int()) {
216 st->print_cr(" " INT32_FORMAT, constants->int_at(cp_index));
217 } else if (tag.is_long()) {
218 st->print_cr(" " INT64_FORMAT, (int64_t)(constants->long_at(cp_index)));
219 } else if (tag.is_float()) {
220 st->print_cr(" %f", constants->float_at(cp_index));
221 } else if (tag.is_double()) {
222 st->print_cr(" %f", constants->double_at(cp_index));
223 } else if (tag.is_string()) {
224 const char* string = constants->unresolved_string_at(cp_index)->as_quoted_ascii();
225 st->print_cr(" \"%s\"", string);
226 } else if (tag.is_klass()) {
227 st->print_cr(" %s", constants->resolved_klass_at(cp_index)->external_name());
228 } else if (tag.is_unresolved_klass()) {
229 st->print_cr(" %s", constants->klass_at_noresolve(cp_index)->as_quoted_ascii());
230 } else if (tag.is_method_type()) {
231 int i2 = constants->method_type_index_at(cp_index);
232 st->print(" <MethodType> %d", i2);
233 st->print_cr(" %s", constants->symbol_at(i2)->as_quoted_ascii());
234 } else if (tag.is_method_handle()) {
235 int kind = constants->method_handle_ref_kind_at(cp_index);
236 int i2 = constants->method_handle_index_at(cp_index);
237 st->print(" <MethodHandle of kind %d index at %d>", kind, i2);
238 print_field_or_method(i2, st);
239 } else if (tag.is_dynamic_constant()) {
240 print_dynamic(cp_index, st);
241 if (ClassPrinter::has_mode(_flags, ClassPrinter::PRINT_DYNAMIC)) {
242 print_bsm(cp_index, st);
243 }
244 } else {
245 st->print_cr(" bad tag=%d at %d", tag.value(), cp_index);
246 }
247 }
248
249 // Fieldref, Methodref, or InterfaceMethodref
250 void BytecodePrinter::print_field_or_method(int cp_index, outputStream* st) {
251 ConstantPool* constants = method()->constants();
252 constantTag tag = constants->tag_at(cp_index);
253
254 switch (tag.value()) {
255 case JVM_CONSTANT_Fieldref:
256 case JVM_CONSTANT_Methodref:
257 case JVM_CONSTANT_InterfaceMethodref:
258 break;
259 default:
260 st->print_cr(" bad tag=%d at %d", tag.value(), cp_index);
261 return;
262 }
263
264 Symbol* name = constants->uncached_name_ref_at(cp_index);
265 Symbol* signature = constants->uncached_signature_ref_at(cp_index);
266 Symbol* klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(cp_index));
267 const char* sep = (tag.is_field() ? ":" : "");
268 st->print_cr(" %d <%s.%s%s%s> ", cp_index, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string());
269 }
270
271 // JVM_CONSTANT_Dynamic or JVM_CONSTANT_InvokeDynamic
272 void BytecodePrinter::print_dynamic(int cp_index, outputStream* st) {
273 ConstantPool* constants = method()->constants();
274 constantTag tag = constants->tag_at(cp_index);
275
276 switch (tag.value()) {
277 case JVM_CONSTANT_Dynamic:
278 case JVM_CONSTANT_InvokeDynamic:
279 break;
280 default:
281 st->print_cr(" bad tag=%d at %d", tag.value(), cp_index);
282 return;
283 }
284
285 int bsm = constants->bootstrap_method_ref_index_at(cp_index);
286 st->print(" bsm=%d", bsm);
287
288 Symbol* name = constants->uncached_name_ref_at(cp_index);
289 Symbol* signature = constants->uncached_signature_ref_at(cp_index);
290 const char* sep = tag.is_dynamic_constant() ? ":" : "";
291 st->print_cr(" %d <%s%s%s>", cp_index, name->as_C_string(), sep, signature->as_C_string());
292 }
293
294 void BytecodePrinter::print_invokedynamic(int indy_index, int cp_index, outputStream* st) {
295 print_dynamic(cp_index, st);
296
297 if (ClassPrinter::has_mode(_flags, ClassPrinter::PRINT_DYNAMIC)) {
298 print_bsm(cp_index, st);
299
300 if (is_linked()) {
301 ResolvedIndyEntry* indy_entry = constants()->resolved_indy_entry_at(indy_index);
302 st->print(" ResolvedIndyEntry: ");
303 indy_entry->print_on(st);
304 }
305 }
306 }
307
308 // cp_index: must be the cp_index of a JVM_CONSTANT_{Dynamic, DynamicInError, InvokeDynamic}
309 void BytecodePrinter::print_bsm(int cp_index, outputStream* st) {
310 assert(constants()->tag_at(cp_index).has_bootstrap(), "must be");
311 int bsm = constants()->bootstrap_method_ref_index_at(cp_index);
312 const char* ref_kind = "";
313 switch (constants()->method_handle_ref_kind_at(bsm)) {
314 case JVM_REF_getField : ref_kind = "REF_getField"; break;
315 case JVM_REF_getStatic : ref_kind = "REF_getStatic"; break;
316 case JVM_REF_putField : ref_kind = "REF_putField"; break;
317 case JVM_REF_putStatic : ref_kind = "REF_putStatic"; break;
318 case JVM_REF_invokeVirtual : ref_kind = "REF_invokeVirtual"; break;
319 case JVM_REF_invokeStatic : ref_kind = "REF_invokeStatic"; break;
320 case JVM_REF_invokeSpecial : ref_kind = "REF_invokeSpecial"; break;
321 case JVM_REF_newInvokeSpecial : ref_kind = "REF_newInvokeSpecial"; break;
322 case JVM_REF_invokeInterface : ref_kind = "REF_invokeInterface"; break;
323 default : ShouldNotReachHere();
324 }
325 st->print(" BSM: %s", ref_kind);
326 print_field_or_method(constants()->method_handle_index_at(bsm), st);
327 int argc = constants()->bootstrap_argument_count_at(cp_index);
328 st->print(" arguments[%d] = {", argc);
329 if (argc > 0) {
330 st->cr();
331 for (int arg_i = 0; arg_i < argc; arg_i++) {
332 int arg = constants()->bootstrap_argument_index_at(cp_index, arg_i);
333 st->print(" ");
334 print_constant(arg, st);
335 }
336 }
337 st->print_cr(" }");
338 }
339
340 void BytecodePrinter::print_attributes(int bci, outputStream* st) {
341 // Show attributes of pre-rewritten codes
342 Bytecodes::Code code = Bytecodes::java_code(raw_code());
343 // If the code doesn't have any fields there's nothing to print.
344 // note this is ==1 because the tableswitch and lookupswitch are
345 // zero size (for some reason) and we want to print stuff out for them.
346 // Also skip this if we're truncating bytecode output
347 if (TraceBytecodesTruncated || Bytecodes::length_for(code) == 1) {
348 st->cr();
349 return;
350 }
351
352 switch(code) {
353 // Java specific bytecodes only matter.
354 case Bytecodes::_bipush:
355 st->print_cr(" " INT32_FORMAT, get_byte());
356 break;
357 case Bytecodes::_sipush:
358 st->print_cr(" " INT32_FORMAT, get_short());
359 break;
360 case Bytecodes::_ldc:
361 {
362 int cp_index;
363 if (Bytecodes::uses_cp_cache(raw_code())) {
364 assert(is_linked(), "fast ldc bytecode must be in linked classes");
365 int obj_index = get_index_u1();
366 cp_index = constants()->object_to_cp_index(obj_index);
367 } else {
368 cp_index = get_index_u1();
369 }
370 print_constant(cp_index, st);
371 }
372 break;
373
374 case Bytecodes::_ldc_w:
375 case Bytecodes::_ldc2_w:
376 {
377 int cp_index;
378 if (Bytecodes::uses_cp_cache(raw_code())) {
379 assert(is_linked(), "fast ldc bytecode must be in linked classes");
380 int obj_index = get_native_index_u2();
381 cp_index = constants()->object_to_cp_index(obj_index);
382 } else {
383 cp_index = get_Java_index_u2();
384 }
385 print_constant(cp_index, st);
386 }
387 break;
388
389 case Bytecodes::_iload:
390 case Bytecodes::_lload:
391 case Bytecodes::_fload:
392 case Bytecodes::_dload:
393 case Bytecodes::_aload:
394 case Bytecodes::_istore:
395 case Bytecodes::_lstore:
396 case Bytecodes::_fstore:
397 case Bytecodes::_dstore:
398 case Bytecodes::_astore:
399 st->print_cr(" #%d", get_index_special());
400 break;
401
402 case Bytecodes::_iinc:
403 { int index = get_index_special();
404 jint offset = is_wide() ? get_short(): get_byte();
405 st->print_cr(" #%d " INT32_FORMAT, index, offset);
406 }
407 break;
408
409 case Bytecodes::_newarray: {
410 BasicType atype = (BasicType)get_index_u1();
411 const char* str = type2name(atype);
412 if (str == nullptr || is_reference_type(atype)) {
413 assert(false, "Unidentified basic type");
414 }
415 st->print_cr(" %s", str);
416 }
417 break;
418 case Bytecodes::_anewarray: {
419 int klass_index = get_Java_index_u2();
420 ConstantPool* constants = method()->constants();
421 Symbol* name = constants->klass_name_at(klass_index);
422 st->print_cr(" %s ", name->as_C_string());
423 }
424 break;
425 case Bytecodes::_multianewarray: {
426 int klass_index = get_Java_index_u2();
427 int nof_dims = get_index_u1();
428 ConstantPool* constants = method()->constants();
429 Symbol* name = constants->klass_name_at(klass_index);
430 st->print_cr(" %s %d", name->as_C_string(), nof_dims);
431 }
432 break;
433
434 case Bytecodes::_ifeq:
435 case Bytecodes::_ifnull:
436 case Bytecodes::_iflt:
437 case Bytecodes::_ifle:
438 case Bytecodes::_ifne:
439 case Bytecodes::_ifnonnull:
440 case Bytecodes::_ifgt:
441 case Bytecodes::_ifge:
442 case Bytecodes::_if_icmpeq:
443 case Bytecodes::_if_icmpne:
444 case Bytecodes::_if_icmplt:
445 case Bytecodes::_if_icmpgt:
446 case Bytecodes::_if_icmple:
447 case Bytecodes::_if_icmpge:
448 case Bytecodes::_if_acmpeq:
449 case Bytecodes::_if_acmpne:
450 case Bytecodes::_goto:
451 case Bytecodes::_jsr:
452 st->print_cr(" %d", bci + get_short());
453 break;
454
455 case Bytecodes::_goto_w:
456 case Bytecodes::_jsr_w:
457 st->print_cr(" %d", bci + get_int());
458 break;
459
460 case Bytecodes::_ret: st->print_cr(" %d", get_index_special()); break;
461
462 case Bytecodes::_tableswitch:
463 { align();
464 int default_dest = bci + get_int();
465 int lo = get_int();
466 int hi = get_int();
467 int len = hi - lo + 1;
468 jint* dest = NEW_RESOURCE_ARRAY(jint, len);
469 for (int i = 0; i < len; i++) {
470 dest[i] = bci + get_int();
471 }
472 st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ",
473 default_dest, lo, hi);
474 const char *comma = "";
475 for (int ll = lo; ll <= hi; ll++) {
476 int idx = ll - lo;
477 st->print("%s %d:" INT32_FORMAT " (delta: %d)", comma, ll, dest[idx], dest[idx]-bci);
478 comma = ",";
479 }
480 st->cr();
481 }
482 break;
483 case Bytecodes::_lookupswitch:
484 { align();
485 int default_dest = bci + get_int();
486 int len = get_int();
487 jint* key = NEW_RESOURCE_ARRAY(jint, len);
488 jint* dest = NEW_RESOURCE_ARRAY(jint, len);
489 for (int i = 0; i < len; i++) {
490 key [i] = get_int();
491 dest[i] = bci + get_int();
492 };
493 st->print(" %d %d ", default_dest, len);
494 const char *comma = "";
495 for (int ll = 0; ll < len; ll++) {
496 st->print("%s " INT32_FORMAT ":" INT32_FORMAT, comma, key[ll], dest[ll]);
497 comma = ",";
498 }
499 st->cr();
500 }
501 break;
502
503 case Bytecodes::_putstatic:
504 case Bytecodes::_getstatic:
505 case Bytecodes::_putfield:
506 case Bytecodes::_getfield:
507 {
508 int cp_index;
509 if (is_linked()) {
510 int field_index = get_native_index_u2();
511 cp_index = cpcache()->resolved_field_entry_at(field_index)->constant_pool_index();
512 } else {
513 cp_index = get_Java_index_u2();
514 }
515 print_field_or_method(cp_index, st);
516 }
517 break;
518
519 case Bytecodes::_invokevirtual:
520 case Bytecodes::_invokespecial:
521 case Bytecodes::_invokestatic:
522 {
523 int cp_index;
524 if (is_linked()) {
525 int method_index = get_native_index_u2();
526 ResolvedMethodEntry* method_entry = cpcache()->resolved_method_entry_at(method_index);
527 cp_index = method_entry->constant_pool_index();
528 print_field_or_method(cp_index, st);
529
530 if (raw_code() == Bytecodes::_invokehandle &&
531 ClassPrinter::has_mode(_flags, ClassPrinter::PRINT_METHOD_HANDLE)) {
532 assert(is_linked(), "invokehandle is only in rewritten methods");
533 method_entry->print_on(st);
534 if (method_entry->has_appendix()) {
535 st->print(" appendix: ");
536 constants()->resolved_reference_from_method(method_index)->print_on(st);
537 }
538 }
539 } else {
540 cp_index = get_Java_index_u2();
541 print_field_or_method(cp_index, st);
542 }
543 }
544 break;
545
546 case Bytecodes::_invokeinterface:
547 {
548 int cp_index;
549 if (is_linked()) {
550 int method_index = get_native_index_u2();
551 cp_index = cpcache()->resolved_method_entry_at(method_index)->constant_pool_index();
552 } else {
553 cp_index = get_Java_index_u2();
554 }
555 int count = get_index_u1(); // TODO: this is not printed.
556 get_byte(); // ignore zero byte
557 print_field_or_method(cp_index, st);
558 }
559 break;
560
561 case Bytecodes::_invokedynamic:
562 {
563 int indy_index;
564 int cp_index;
565 if (is_linked()) {
566 indy_index = get_native_index_u4();
567 cp_index = constants()->resolved_indy_entry_at(indy_index)->constant_pool_index();
568 } else {
569 indy_index = -1;
570 cp_index = get_Java_index_u2();
571 get_byte(); // ignore zero byte
572 get_byte(); // ignore zero byte
573 }
574 print_invokedynamic(indy_index, cp_index, st);
575 }
576 break;
577
578 case Bytecodes::_new:
579 case Bytecodes::_checkcast:
580 case Bytecodes::_instanceof:
581 { int i = get_Java_index_u2();
582 ConstantPool* constants = method()->constants();
583 Symbol* name = constants->klass_name_at(i);
584 st->print_cr(" %d <%s>", i, name->as_C_string());
585 }
586 break;
587
588 case Bytecodes::_wide:
589 // length is zero not one, but printed with no more info.
590 break;
591
592 default:
593 ShouldNotReachHere();
594 break;
595 }
596 }
597
598
599 void BytecodePrinter::bytecode_epilog(int bci, outputStream* st) {
600 MethodData* mdo = method()->method_data();
601 if (mdo != nullptr) {
602
603 // Lock to read ProfileData, and ensure lock is not broken by a safepoint
604 MutexLocker ml(mdo->extra_data_lock(), Mutex::_no_safepoint_check_flag);
605
606 ProfileData* data = mdo->bci_to_data(bci);
607 if (data != nullptr) {
608 st->print(" %d ", mdo->dp_to_di(data->dp()));
609 st->fill_to(7);
610 data->print_data_on(st, mdo);
611 }
612 }
613 }