bytecodeTracer.cpp revision 844:bd02caa94611
1254721Semaste/*
2254721Semaste * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
3254721Semaste * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4254721Semaste *
5254721Semaste * This code is free software; you can redistribute it and/or modify it
6254721Semaste * under the terms of the GNU General Public License version 2 only, as
7254721Semaste * published by the Free Software Foundation.
8254721Semaste *
9254721Semaste * This code is distributed in the hope that it will be useful, but WITHOUT
10254721Semaste * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11254721Semaste * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12254721Semaste * version 2 for more details (a copy is included in the LICENSE file that
13254721Semaste * accompanied this code).
14254721Semaste *
15254721Semaste * You should have received a copy of the GNU General Public License version
16254721Semaste * 2 along with this work; if not, write to the Free Software Foundation,
17254721Semaste * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18254721Semaste *
19254721Semaste * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20254721Semaste * CA 95054 USA or visit www.sun.com if you need additional information or
21254721Semaste * have any questions.
22254721Semaste *
23254721Semaste */
24254721Semaste
25254721Semaste#include "incls/_precompiled.incl"
26254721Semaste#include "incls/_bytecodeTracer.cpp.incl"
27254721Semaste
28254721Semaste
29254721Semaste#ifndef PRODUCT
30254721Semaste
31254721Semaste// Standard closure for BytecodeTracer: prints the current bytecode
32254721Semaste// and its attributes using bytecode-specific information.
33254721Semaste
34254721Semasteclass BytecodePrinter: public BytecodeClosure {
35254721Semaste private:
36254721Semaste  // %%% This field is not GC-ed, and so can contain garbage
37254721Semaste  // between critical sections.  Use only pointer-comparison
38254721Semaste  // operations on the pointer, except within a critical section.
39254721Semaste  // (Also, ensure that occasional false positives are benign.)
40254721Semaste  methodOop _current_method;
41254721Semaste  bool      _is_wide;
42254721Semaste  address   _next_pc;                // current decoding position
43254721Semaste
44254721Semaste  void      align()                  { _next_pc = (address)round_to((intptr_t)_next_pc, sizeof(jint)); }
45254721Semaste  int       get_byte()               { return *(jbyte*) _next_pc++; }  // signed
46254721Semaste  short     get_short()              { short i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; }
47254721Semaste  int       get_int()                { int i=Bytes::get_Java_u4(_next_pc); _next_pc+=4; return i; }
48254721Semaste
49254721Semaste  int       get_index()              { return *(address)_next_pc++; }
50254721Semaste  int       get_big_index()          { int i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; }
51254721Semaste  int       get_giant_index()        { int i=Bytes::get_native_u4(_next_pc); _next_pc+=4; return i; }
52254721Semaste  int       get_index_special()      { return (is_wide()) ? get_big_index() : get_index(); }
53254721Semaste  methodOop method()                 { return _current_method; }
54254721Semaste  bool      is_wide()                { return _is_wide; }
55254721Semaste
56254721Semaste
57254721Semaste  bool      check_index(int i, bool in_cp_cache, int& cp_index, outputStream* st = tty);
58254721Semaste  void      print_constant(int i, outputStream* st = tty);
59254721Semaste  void      print_field_or_method(int i, outputStream* st = tty);
60254721Semaste  void      print_attributes(Bytecodes::Code code, int bci, outputStream* st = tty);
61254721Semaste  void      bytecode_epilog(int bci, outputStream* st = tty);
62254721Semaste
63254721Semaste public:
64254721Semaste  BytecodePrinter() {
65254721Semaste    _is_wide = false;
66254721Semaste  }
67254721Semaste
68254721Semaste  // This method is called while executing the raw bytecodes, so none of
69254721Semaste  // the adjustments that BytecodeStream performs applies.
70254721Semaste  void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
71254721Semaste    ResourceMark rm;
72254721Semaste    if (_current_method != method()) {
73254721Semaste      // Note 1: This code will not work as expected with true MT/MP.
74254721Semaste      //         Need an explicit lock or a different solution.
75254721Semaste      // It is possible for this block to be skipped, if a garbage
76254721Semaste      // _current_method pointer happens to have the same bits as
77254721Semaste      // the incoming method.  We could lose a line of trace output.
78254721Semaste      // This is acceptable in a debug-only feature.
79254721Semaste      st->cr();
80254721Semaste      st->print("[%d] ", (int) Thread::current()->osthread()->thread_id());
81254721Semaste      method->print_name(st);
82254721Semaste      st->cr();
83254721Semaste      _current_method = method();
84254721Semaste    }
85254721Semaste    Bytecodes::Code code;
86254721Semaste    if (is_wide()) {
87254721Semaste      // bcp wasn't advanced if previous bytecode was _wide.
88254721Semaste      code = Bytecodes::code_at(bcp+1);
89254721Semaste    } else {
90254721Semaste      code = Bytecodes::code_at(bcp);
91254721Semaste    }
92254721Semaste    int bci = bcp - method->code_base();
93254721Semaste    st->print("[%d] ", (int) Thread::current()->osthread()->thread_id());
94254721Semaste    if (Verbose) {
95254721Semaste      st->print("%8d  %4d  " INTPTR_FORMAT " " INTPTR_FORMAT " %s",
96254721Semaste           BytecodeCounter::counter_value(), bci, tos, tos2, Bytecodes::name(code));
97254721Semaste    } else {
98254721Semaste      st->print("%8d  %4d  %s",
99254721Semaste           BytecodeCounter::counter_value(), bci, Bytecodes::name(code));
100254721Semaste    }
101254721Semaste    _next_pc = is_wide() ? bcp+2 : bcp+1;
102254721Semaste    print_attributes(code, bci);
103254721Semaste    // Set is_wide for the next one, since the caller of this doesn't skip
104254721Semaste    // the next bytecode.
105254721Semaste    _is_wide = (code == Bytecodes::_wide);
106254721Semaste  }
107254721Semaste
108254721Semaste  // Used for methodOop::print_codes().  The input bcp comes from
109254721Semaste  // BytecodeStream, which will skip wide bytecodes.
110254721Semaste  void trace(methodHandle method, address bcp, outputStream* st) {
111254721Semaste    _current_method = method();
112254721Semaste    ResourceMark rm;
113254721Semaste    Bytecodes::Code code = Bytecodes::code_at(bcp);
114254721Semaste    // Set is_wide
115254721Semaste    _is_wide = (code == Bytecodes::_wide);
116254721Semaste    if (is_wide()) {
117254721Semaste      code = Bytecodes::code_at(bcp+1);
118254721Semaste    }
119254721Semaste    int bci = bcp - method->code_base();
120254721Semaste    // Print bytecode index and name
121254721Semaste    if (is_wide()) {
122254721Semaste      st->print("%d %s_w", bci, Bytecodes::name(code));
123254721Semaste    } else {
124254721Semaste      st->print("%d %s", bci, Bytecodes::name(code));
125254721Semaste    }
126254721Semaste    _next_pc = is_wide() ? bcp+2 : bcp+1;
127254721Semaste    print_attributes(code, bci, st);
128254721Semaste    bytecode_epilog(bci, st);
129254721Semaste  }
130254721Semaste};
131254721Semaste
132254721Semaste
133254721Semaste// Implementation of BytecodeTracer
134254721Semaste
135254721Semaste// %%% This set_closure thing seems overly general, given that
136254721Semaste// nobody uses it.  Also, if BytecodePrinter weren't hidden
137254721Semaste// then methodOop could use instances of it directly and it
138254721Semaste// would be easier to remove races on _current_method and bcp.
139254721Semaste// Since this is not product functionality, we can defer cleanup.
140254721Semaste
141254721SemasteBytecodeClosure* BytecodeTracer::_closure = NULL;
142254721Semaste
143254721Semastestatic BytecodePrinter std_closure;
144254721SemasteBytecodeClosure* BytecodeTracer::std_closure() {
145254721Semaste  return &::std_closure;
146254721Semaste}
147254721Semaste
148254721Semaste
149254721Semastevoid BytecodeTracer::trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
150254721Semaste  if (TraceBytecodes && BytecodeCounter::counter_value() >= TraceBytecodesAt) {
151254721Semaste    ttyLocker ttyl;  // 5065316: keep the following output coherent
152254721Semaste    // The ttyLocker also prevents races between two threads
153254721Semaste    // trying to use the single instance of BytecodePrinter.
154254721Semaste    // Using the ttyLocker prevents the system from coming to
155254721Semaste    // a safepoint within this code, which is sensitive to methodOop
156254721Semaste    // movement.
157254721Semaste    //
158254721Semaste    // There used to be a leaf mutex here, but the ttyLocker will
159254721Semaste    // work just as well, as long as the printing operations never block.
160254721Semaste    //
161254721Semaste    // We put the locker on the static trace method, not the
162254721Semaste    // virtual one, because the clients of this module go through
163254721Semaste    // the static method.
164254721Semaste    _closure->trace(method, bcp, tos, tos2, st);
165254721Semaste  }
166254721Semaste}
167254721Semaste
168254721Semastevoid BytecodeTracer::trace(methodHandle method, address bcp, outputStream* st) {
169254721Semaste  ttyLocker ttyl;  // 5065316: keep the following output coherent
170254721Semaste  _closure->trace(method, bcp, st);
171254721Semaste}
172254721Semaste
173254721Semastevoid print_oop(oop value, outputStream* st) {
174254721Semaste  if (value == NULL) {
175254721Semaste    st->print_cr(" NULL");
176254721Semaste  } else {
177254721Semaste    EXCEPTION_MARK;
178254721Semaste    Handle h_value (THREAD, value);
179254721Semaste    symbolHandle sym = java_lang_String::as_symbol(h_value, CATCH);
180254721Semaste    if (sym->utf8_length() > 32) {
181254721Semaste      st->print_cr(" ....");
182254721Semaste    } else {
183254721Semaste      sym->print_on(st); st->cr();
184254721Semaste    }
185254721Semaste  }
186254721Semaste}
187254721Semaste
188254721Semastebool BytecodePrinter::check_index(int i, bool in_cp_cache, int& cp_index, outputStream* st) {
189254721Semaste  constantPoolOop constants = method()->constants();
190254721Semaste  int ilimit = constants->length(), climit = 0;
191254721Semaste
192254721Semaste  constantPoolCacheOop cache = NULL;
193254721Semaste  if (in_cp_cache) {
194254721Semaste    cache = constants->cache();
195254721Semaste    if (cache != NULL) {
196254721Semaste      //climit = cache->length();  // %%% private!
197254721Semaste      size_t size = cache->size() * HeapWordSize;
198254721Semaste      size -= sizeof(constantPoolCacheOopDesc);
199254721Semaste      size /= sizeof(ConstantPoolCacheEntry);
200254721Semaste      climit = (int) size;
201254721Semaste    }
202254721Semaste  }
203254721Semaste
204254721Semaste  if (in_cp_cache && constantPoolCacheOopDesc::is_secondary_index(i)) {
205254721Semaste    i = constantPoolCacheOopDesc::decode_secondary_index(i);
206254721Semaste    st->print(" secondary cache[%d] of", i);
207254721Semaste    if (i >= 0 && i < climit) {
208254721Semaste      if (!cache->entry_at(i)->is_secondary_entry()) {
209254721Semaste        st->print_cr(" not secondary entry?", i);
210254721Semaste        return false;
211254721Semaste      }
212254721Semaste      i = cache->entry_at(i)->main_entry_index();
213254721Semaste      goto check_cache_index;
214254721Semaste    } else {
215254721Semaste      st->print_cr(" not in cache[*]?", i);
216254721Semaste      return false;
217254721Semaste    }
218254721Semaste  }
219254721Semaste
220254721Semaste  if (cache != NULL) {
221254721Semaste    i = Bytes::swap_u2(i);
222254721Semaste    if (WizardMode)  st->print(" (swap=%d)", i);
223254721Semaste    goto check_cache_index;
224254721Semaste  }
225254721Semaste
226254721Semaste check_cp_index:
227254721Semaste  if (i >= 0 && i < ilimit) {
228254721Semaste    if (WizardMode)  st->print(" cp[%d]", i);
229254721Semaste    cp_index = i;
230254721Semaste    return true;
231254721Semaste  }
232254721Semaste
233254721Semaste  st->print_cr(" CP[%d] not in CP", i);
234254721Semaste  return false;
235254721Semaste
236254721Semaste check_cache_index:
237254721Semaste  if (i >= 0 && i < climit) {
238254721Semaste    if (cache->entry_at(i)->is_secondary_entry()) {
239254721Semaste      st->print_cr(" secondary entry?");
240254721Semaste      return false;
241254721Semaste    }
242254721Semaste    i = cache->entry_at(i)->constant_pool_index();
243254721Semaste    goto check_cp_index;
244254721Semaste  }
245254721Semaste  st->print_cr(" not in CP[*]?", i);
246254721Semaste  return false;
247254721Semaste}
248254721Semaste
249254721Semastevoid BytecodePrinter::print_constant(int i, outputStream* st) {
250254721Semaste  int orig_i = i;
251254721Semaste  if (!check_index(orig_i, false, i, st))  return;
252254721Semaste
253254721Semaste  constantPoolOop constants = method()->constants();
254254721Semaste  constantTag tag = constants->tag_at(i);
255254721Semaste
256254721Semaste  if (tag.is_int()) {
257254721Semaste    st->print_cr(" " INT32_FORMAT, constants->int_at(i));
258254721Semaste  } else if (tag.is_long()) {
259254721Semaste    st->print_cr(" " INT64_FORMAT, constants->long_at(i));
260254721Semaste  } else if (tag.is_float()) {
261254721Semaste    st->print_cr(" %f", constants->float_at(i));
262254721Semaste  } else if (tag.is_double()) {
263254721Semaste    st->print_cr(" %f", constants->double_at(i));
264254721Semaste  } else if (tag.is_string()) {
265254721Semaste    oop string = constants->resolved_string_at(i);
266254721Semaste    print_oop(string, st);
267254721Semaste  } else if (tag.is_unresolved_string()) {
268254721Semaste    st->print_cr(" <unresolved string at %d>", i);
269254721Semaste  } else if (tag.is_klass()) {
270254721Semaste    st->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name());
271254721Semaste  } else if (tag.is_unresolved_klass()) {
272254721Semaste    st->print_cr(" <unresolved klass at %d>", i);
273254721Semaste  } else {
274254721Semaste    st->print_cr(" bad tag=%d at %d", tag.value(), i);
275254721Semaste  }
276254721Semaste}
277254721Semaste
278254721Semastevoid BytecodePrinter::print_field_or_method(int i, outputStream* st) {
279254721Semaste  int orig_i = i;
280254721Semaste  if (!check_index(orig_i, true, i, st))  return;
281254721Semaste
282254721Semaste  constantPoolOop constants = method()->constants();
283254721Semaste  constantTag tag = constants->tag_at(i);
284254721Semaste
285254721Semaste  switch (tag.value()) {
286254721Semaste  case JVM_CONSTANT_InterfaceMethodref:
287254721Semaste  case JVM_CONSTANT_Methodref:
288254721Semaste  case JVM_CONSTANT_Fieldref:
289254721Semaste    break;
290254721Semaste  default:
291254721Semaste    st->print_cr(" bad tag=%d at %d", tag.value(), i);
292254721Semaste    return;
293254721Semaste  }
294254721Semaste
295254721Semaste  symbolOop name = constants->name_ref_at(orig_i);
296254721Semaste  symbolOop signature = constants->signature_ref_at(orig_i);
297254721Semaste  st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string());
298254721Semaste}
299254721Semaste
300254721Semaste
301254721Semastevoid BytecodePrinter::print_attributes(Bytecodes::Code code, int bci, outputStream* st) {
302254721Semaste  // Show attributes of pre-rewritten codes
303254721Semaste  code = Bytecodes::java_code(code);
304254721Semaste  // If the code doesn't have any fields there's nothing to print.
305254721Semaste  // note this is ==1 because the tableswitch and lookupswitch are
306254721Semaste  // zero size (for some reason) and we want to print stuff out for them.
307254721Semaste  if (Bytecodes::length_for(code) == 1) {
308254721Semaste    st->cr();
309254721Semaste    return;
310254721Semaste  }
311254721Semaste
312254721Semaste  switch(code) {
313254721Semaste    // Java specific bytecodes only matter.
314254721Semaste    case Bytecodes::_bipush:
315254721Semaste      st->print_cr(" " INT32_FORMAT, get_byte());
316254721Semaste      break;
317254721Semaste    case Bytecodes::_sipush:
318254721Semaste      st->print_cr(" " INT32_FORMAT, get_short());
319254721Semaste      break;
320254721Semaste    case Bytecodes::_ldc:
321254721Semaste      print_constant(get_index(), st);
322254721Semaste      break;
323254721Semaste
324254721Semaste    case Bytecodes::_ldc_w:
325254721Semaste    case Bytecodes::_ldc2_w:
326254721Semaste      print_constant(get_big_index(), st);
327254721Semaste      break;
328254721Semaste
329254721Semaste    case Bytecodes::_iload:
330254721Semaste    case Bytecodes::_lload:
331254721Semaste    case Bytecodes::_fload:
332254721Semaste    case Bytecodes::_dload:
333254721Semaste    case Bytecodes::_aload:
334254721Semaste    case Bytecodes::_istore:
335254721Semaste    case Bytecodes::_lstore:
336254721Semaste    case Bytecodes::_fstore:
337254721Semaste    case Bytecodes::_dstore:
338254721Semaste    case Bytecodes::_astore:
339254721Semaste      st->print_cr(" #%d", get_index_special());
340254721Semaste      break;
341254721Semaste
342254721Semaste    case Bytecodes::_iinc:
343254721Semaste      { int index = get_index_special();
344254721Semaste        jint offset = is_wide() ? get_short(): get_byte();
345254721Semaste        st->print_cr(" #%d " INT32_FORMAT, index, offset);
346254721Semaste      }
347254721Semaste      break;
348254721Semaste
349254721Semaste    case Bytecodes::_newarray: {
350254721Semaste        BasicType atype = (BasicType)get_index();
351254721Semaste        const char* str = type2name(atype);
352254721Semaste        if (str == NULL || atype == T_OBJECT || atype == T_ARRAY) {
353254721Semaste          assert(false, "Unidentified basic type");
354254721Semaste        }
355254721Semaste        st->print_cr(" %s", str);
356254721Semaste      }
357254721Semaste      break;
358254721Semaste    case Bytecodes::_anewarray: {
359254721Semaste        int klass_index = get_big_index();
360254721Semaste        constantPoolOop constants = method()->constants();
361254721Semaste        symbolOop name = constants->klass_name_at(klass_index);
362254721Semaste        st->print_cr(" %s ", name->as_C_string());
363254721Semaste      }
364254721Semaste      break;
365254721Semaste    case Bytecodes::_multianewarray: {
366254721Semaste        int klass_index = get_big_index();
367254721Semaste        int nof_dims = get_index();
368254721Semaste        constantPoolOop constants = method()->constants();
369254721Semaste        symbolOop name = constants->klass_name_at(klass_index);
370254721Semaste        st->print_cr(" %s %d", name->as_C_string(), nof_dims);
371254721Semaste      }
372254721Semaste      break;
373254721Semaste
374254721Semaste    case Bytecodes::_ifeq:
375254721Semaste    case Bytecodes::_ifnull:
376254721Semaste    case Bytecodes::_iflt:
377254721Semaste    case Bytecodes::_ifle:
378254721Semaste    case Bytecodes::_ifne:
379254721Semaste    case Bytecodes::_ifnonnull:
380254721Semaste    case Bytecodes::_ifgt:
381254721Semaste    case Bytecodes::_ifge:
382254721Semaste    case Bytecodes::_if_icmpeq:
383254721Semaste    case Bytecodes::_if_icmpne:
384254721Semaste    case Bytecodes::_if_icmplt:
385254721Semaste    case Bytecodes::_if_icmpgt:
386254721Semaste    case Bytecodes::_if_icmple:
387254721Semaste    case Bytecodes::_if_icmpge:
388254721Semaste    case Bytecodes::_if_acmpeq:
389254721Semaste    case Bytecodes::_if_acmpne:
390254721Semaste    case Bytecodes::_goto:
391254721Semaste    case Bytecodes::_jsr:
392254721Semaste      st->print_cr(" %d", bci + get_short());
393254721Semaste      break;
394254721Semaste
395254721Semaste    case Bytecodes::_goto_w:
396254721Semaste    case Bytecodes::_jsr_w:
397254721Semaste      st->print_cr(" %d", bci + get_int());
398254721Semaste      break;
399254721Semaste
400254721Semaste    case Bytecodes::_ret: st->print_cr(" %d", get_index_special()); break;
401254721Semaste
402254721Semaste    case Bytecodes::_tableswitch:
403254721Semaste      { align();
404254721Semaste        int  default_dest = bci + get_int();
405254721Semaste        int  lo           = get_int();
406254721Semaste        int  hi           = get_int();
407254721Semaste        int  len          = hi - lo + 1;
408254721Semaste        jint* dest        = NEW_RESOURCE_ARRAY(jint, len);
409254721Semaste        for (int i = 0; i < len; i++) {
410254721Semaste          dest[i] = bci + get_int();
411254721Semaste        }
412254721Semaste        st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ",
413254721Semaste                      default_dest, lo, hi);
414254721Semaste        int first = true;
415254721Semaste        for (int ll = lo; ll <= hi; ll++, first = false)  {
416254721Semaste          int idx = ll - lo;
417254721Semaste          const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" :
418254721Semaste                                       ", %d:" INT32_FORMAT " (delta: %d)";
419254721Semaste          st->print(format, ll, dest[idx], dest[idx]-bci);
420254721Semaste        }
421254721Semaste        st->cr();
422254721Semaste      }
423254721Semaste      break;
424254721Semaste    case Bytecodes::_lookupswitch:
425254721Semaste      { align();
426254721Semaste        int  default_dest = bci + get_int();
427254721Semaste        int  len          = get_int();
428254721Semaste        jint* key         = NEW_RESOURCE_ARRAY(jint, len);
429254721Semaste        jint* dest        = NEW_RESOURCE_ARRAY(jint, len);
430254721Semaste        for (int i = 0; i < len; i++) {
431254721Semaste          key [i] = get_int();
432254721Semaste          dest[i] = bci + get_int();
433254721Semaste        };
434254721Semaste        st->print(" %d %d ", default_dest, len);
435254721Semaste        bool first = true;
436254721Semaste        for (int ll = 0; ll < len; ll++, first = false)  {
437254721Semaste          const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT :
438254721Semaste                                       ", " INT32_FORMAT ":" INT32_FORMAT ;
439254721Semaste          st->print(format, key[ll], dest[ll]);
440254721Semaste        }
441254721Semaste        st->cr();
442254721Semaste      }
443254721Semaste      break;
444254721Semaste
445254721Semaste    case Bytecodes::_putstatic:
446254721Semaste    case Bytecodes::_getstatic:
447254721Semaste    case Bytecodes::_putfield:
448254721Semaste    case Bytecodes::_getfield:
449254721Semaste      print_field_or_method(get_big_index(), st);
450254721Semaste      break;
451254721Semaste
452254721Semaste    case Bytecodes::_invokevirtual:
453254721Semaste    case Bytecodes::_invokespecial:
454254721Semaste    case Bytecodes::_invokestatic:
455254721Semaste      print_field_or_method(get_big_index(), st);
456254721Semaste      break;
457254721Semaste
458254721Semaste    case Bytecodes::_invokeinterface:
459254721Semaste      { int i = get_big_index();
460254721Semaste        int n = get_index();
461254721Semaste        get_index();            // ignore zero byte
462254721Semaste        print_field_or_method(i, st);
463254721Semaste      }
464254721Semaste      break;
465254721Semaste
466254721Semaste    case Bytecodes::_invokedynamic:
467254721Semaste      print_field_or_method(get_giant_index(), st);
468254721Semaste      break;
469254721Semaste
470254721Semaste    case Bytecodes::_new:
471254721Semaste    case Bytecodes::_checkcast:
472254721Semaste    case Bytecodes::_instanceof:
473254721Semaste      { int i = get_big_index();
474254721Semaste        constantPoolOop constants = method()->constants();
475254721Semaste        symbolOop name = constants->klass_name_at(i);
476254721Semaste        st->print_cr(" %d <%s>", i, name->as_C_string());
477254721Semaste      }
478254721Semaste      break;
479254721Semaste
480254721Semaste    case Bytecodes::_wide:
481254721Semaste      // length is zero not one, but printed with no more info.
482254721Semaste      break;
483254721Semaste
484254721Semaste    default:
485254721Semaste      ShouldNotReachHere();
486254721Semaste      break;
487254721Semaste  }
488254721Semaste}
489254721Semaste
490254721Semaste
491254721Semastevoid BytecodePrinter::bytecode_epilog(int bci, outputStream* st) {
492254721Semaste  methodDataOop mdo = method()->method_data();
493254721Semaste  if (mdo != NULL) {
494254721Semaste    ProfileData* data = mdo->bci_to_data(bci);
495254721Semaste    if (data != NULL) {
496254721Semaste      st->print("  %d", mdo->dp_to_di(data->dp()));
497254721Semaste      st->fill_to(6);
498254721Semaste      data->print_data_on(st);
499254721Semaste    }
500254721Semaste  }
501254721Semaste}
502254721Semaste#endif // PRODUCT
503254721Semaste