bytecodeTracer.cpp 19.6 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32 33 34 35
#include "precompiled.hpp"
#include "interpreter/bytecodeHistogram.hpp"
#include "interpreter/bytecodeTracer.hpp"
#include "interpreter/bytecodes.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/resourceArea.hpp"
#include "oops/methodDataOop.hpp"
#include "oops/methodOop.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/timer.hpp"
D
duke 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50


#ifndef PRODUCT

// Standard closure for BytecodeTracer: prints the current bytecode
// and its attributes using bytecode-specific information.

class BytecodePrinter: public BytecodeClosure {
 private:
  // %%% This field is not GC-ed, and so can contain garbage
  // between critical sections.  Use only pointer-comparison
  // operations on the pointer, except within a critical section.
  // (Also, ensure that occasional false positives are benign.)
  methodOop _current_method;
  bool      _is_wide;
51
  Bytecodes::Code _code;
D
duke 已提交
52 53 54 55 56 57 58
  address   _next_pc;                // current decoding position

  void      align()                  { _next_pc = (address)round_to((intptr_t)_next_pc, sizeof(jint)); }
  int       get_byte()               { return *(jbyte*) _next_pc++; }  // signed
  short     get_short()              { short i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; }
  int       get_int()                { int i=Bytes::get_Java_u4(_next_pc); _next_pc+=4; return i; }

59 60
  int       get_index_u1()           { return *(address)_next_pc++; }
  int       get_index_u2()           { int i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; }
61
  int       get_index_u1_cpcache()   { return get_index_u1() + constantPoolOopDesc::CPCACHE_INDEX_TAG; }
62 63 64
  int       get_index_u2_cpcache()   { int i=Bytes::get_native_u2(_next_pc); _next_pc+=2; return i + constantPoolOopDesc::CPCACHE_INDEX_TAG; }
  int       get_index_u4()           { int i=Bytes::get_native_u4(_next_pc); _next_pc+=4; return i; }
  int       get_index_special()      { return (is_wide()) ? get_index_u2() : get_index_u1(); }
D
duke 已提交
65 66
  methodOop method()                 { return _current_method; }
  bool      is_wide()                { return _is_wide; }
67
  Bytecodes::Code raw_code()         { return Bytecodes::Code(_code); }
D
duke 已提交
68 69


70
  bool      check_index(int i, int& cp_index, outputStream* st = tty);
D
duke 已提交
71
  void      print_constant(int i, outputStream* st = tty);
72
  void      print_field_or_method(int i, outputStream* st = tty);
73
  void      print_field_or_method(int orig_i, int i, outputStream* st = tty);
74
  void      print_attributes(int bci, outputStream* st = tty);
D
duke 已提交
75 76 77 78 79
  void      bytecode_epilog(int bci, outputStream* st = tty);

 public:
  BytecodePrinter() {
    _is_wide = false;
80
    _code = Bytecodes::_illegal;
D
duke 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94
  }

  // This method is called while executing the raw bytecodes, so none of
  // the adjustments that BytecodeStream performs applies.
  void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
    ResourceMark rm;
    if (_current_method != method()) {
      // Note 1: This code will not work as expected with true MT/MP.
      //         Need an explicit lock or a different solution.
      // It is possible for this block to be skipped, if a garbage
      // _current_method pointer happens to have the same bits as
      // the incoming method.  We could lose a line of trace output.
      // This is acceptable in a debug-only feature.
      st->cr();
N
never 已提交
95
      st->print("[%ld] ", (long) Thread::current()->osthread()->thread_id());
D
duke 已提交
96 97 98 99 100 101 102
      method->print_name(st);
      st->cr();
      _current_method = method();
    }
    Bytecodes::Code code;
    if (is_wide()) {
      // bcp wasn't advanced if previous bytecode was _wide.
103
      code = Bytecodes::code_at(method(), bcp+1);
D
duke 已提交
104
    } else {
105
      code = Bytecodes::code_at(method(), bcp);
D
duke 已提交
106
    }
107 108
    _code = code;
     int bci = bcp - method->code_base();
N
never 已提交
109
    st->print("[%ld] ", (long) Thread::current()->osthread()->thread_id());
D
duke 已提交
110 111 112 113 114 115 116 117
    if (Verbose) {
      st->print("%8d  %4d  " INTPTR_FORMAT " " INTPTR_FORMAT " %s",
           BytecodeCounter::counter_value(), bci, tos, tos2, Bytecodes::name(code));
    } else {
      st->print("%8d  %4d  %s",
           BytecodeCounter::counter_value(), bci, Bytecodes::name(code));
    }
    _next_pc = is_wide() ? bcp+2 : bcp+1;
118
    print_attributes(bci);
D
duke 已提交
119 120 121
    // Set is_wide for the next one, since the caller of this doesn't skip
    // the next bytecode.
    _is_wide = (code == Bytecodes::_wide);
122
    _code = Bytecodes::_illegal;
D
duke 已提交
123 124 125 126 127 128 129
  }

  // Used for methodOop::print_codes().  The input bcp comes from
  // BytecodeStream, which will skip wide bytecodes.
  void trace(methodHandle method, address bcp, outputStream* st) {
    _current_method = method();
    ResourceMark rm;
130
    Bytecodes::Code code = Bytecodes::code_at(method(), bcp);
D
duke 已提交
131 132 133
    // Set is_wide
    _is_wide = (code == Bytecodes::_wide);
    if (is_wide()) {
134
      code = Bytecodes::code_at(method(), bcp+1);
D
duke 已提交
135
    }
136
    _code = code;
D
duke 已提交
137 138 139 140 141 142 143 144
    int bci = bcp - method->code_base();
    // Print bytecode index and name
    if (is_wide()) {
      st->print("%d %s_w", bci, Bytecodes::name(code));
    } else {
      st->print("%d %s", bci, Bytecodes::name(code));
    }
    _next_pc = is_wide() ? bcp+2 : bcp+1;
145
    print_attributes(bci, st);
D
duke 已提交
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
    bytecode_epilog(bci, st);
  }
};


// Implementation of BytecodeTracer

// %%% This set_closure thing seems overly general, given that
// nobody uses it.  Also, if BytecodePrinter weren't hidden
// then methodOop could use instances of it directly and it
// would be easier to remove races on _current_method and bcp.
// Since this is not product functionality, we can defer cleanup.

BytecodeClosure* BytecodeTracer::_closure = NULL;

static BytecodePrinter std_closure;
BytecodeClosure* BytecodeTracer::std_closure() {
  return &::std_closure;
}


void BytecodeTracer::trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
  if (TraceBytecodes && BytecodeCounter::counter_value() >= TraceBytecodesAt) {
    ttyLocker ttyl;  // 5065316: keep the following output coherent
    // The ttyLocker also prevents races between two threads
    // trying to use the single instance of BytecodePrinter.
    // Using the ttyLocker prevents the system from coming to
    // a safepoint within this code, which is sensitive to methodOop
    // movement.
    //
    // There used to be a leaf mutex here, but the ttyLocker will
    // work just as well, as long as the printing operations never block.
    //
    // We put the locker on the static trace method, not the
    // virtual one, because the clients of this module go through
    // the static method.
    _closure->trace(method, bcp, tos, tos2, st);
  }
}

void BytecodeTracer::trace(methodHandle method, address bcp, outputStream* st) {
  ttyLocker ttyl;  // 5065316: keep the following output coherent
  _closure->trace(method, bcp, st);
}

191
void print_symbol(Symbol* sym, outputStream* st) {
192 193 194 195 196 197 198 199 200 201
  char buf[40];
  int len = sym->utf8_length();
  if (len >= (int)sizeof(buf)) {
    st->print_cr(" %s...[%d]", sym->as_C_string(buf, sizeof(buf)), len);
  } else {
    st->print(" ");
    sym->print_on(st); st->cr();
  }
}

D
duke 已提交
202 203 204
void print_oop(oop value, outputStream* st) {
  if (value == NULL) {
    st->print_cr(" NULL");
205
  } else if (java_lang_String::is_instance(value)) {
206 207 208 209 210 211 212 213
    char buf[40];
    int len = java_lang_String::utf8_length(value);
    java_lang_String::as_utf8_string(value, buf, sizeof(buf));
    if (len >= (int)sizeof(buf)) {
      st->print_cr(" %s...[%d]", buf, len);
    } else {
      st->print_cr(" %s", buf);
    }
214 215
  } else {
    st->print_cr(" " PTR_FORMAT, (intptr_t) value);
D
duke 已提交
216 217 218
  }
}

219
bool BytecodePrinter::check_index(int i, int& cp_index, outputStream* st) {
220 221
  constantPoolOop constants = method()->constants();
  int ilimit = constants->length(), climit = 0;
222
  Bytecodes::Code code = raw_code();
223 224

  constantPoolCacheOop cache = NULL;
225
  if (Bytecodes::uses_cp_cache(code)) {
226 227 228 229 230 231 232 233 234 235
    cache = constants->cache();
    if (cache != NULL) {
      //climit = cache->length();  // %%% private!
      size_t size = cache->size() * HeapWordSize;
      size -= sizeof(constantPoolCacheOopDesc);
      size /= sizeof(ConstantPoolCacheEntry);
      climit = (int) size;
    }
  }

236
  if (cache != NULL && constantPoolCacheOopDesc::is_secondary_index(i)) {
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
    i = constantPoolCacheOopDesc::decode_secondary_index(i);
    st->print(" secondary cache[%d] of", i);
    if (i >= 0 && i < climit) {
      if (!cache->entry_at(i)->is_secondary_entry()) {
        st->print_cr(" not secondary entry?", i);
        return false;
      }
      i = cache->entry_at(i)->main_entry_index();
      goto check_cache_index;
    } else {
      st->print_cr(" not in cache[*]?", i);
      return false;
    }
  }

  if (cache != NULL) {
    goto check_cache_index;
  }

 check_cp_index:
  if (i >= 0 && i < ilimit) {
    if (WizardMode)  st->print(" cp[%d]", i);
    cp_index = i;
    return true;
  }

  st->print_cr(" CP[%d] not in CP", i);
  return false;

 check_cache_index:
267 268 269 270 271 272 273 274 275 276 277
#ifdef ASSERT
  {
    const int CPCACHE_INDEX_TAG = constantPoolOopDesc::CPCACHE_INDEX_TAG;
    if (i >= CPCACHE_INDEX_TAG && i < climit + CPCACHE_INDEX_TAG) {
      i -= CPCACHE_INDEX_TAG;
    } else {
      st->print_cr(" CP[%d] missing bias?", i);
      return false;
    }
  }
#endif //ASSERT
278 279 280 281 282 283 284 285 286 287 288 289
  if (i >= 0 && i < climit) {
    if (cache->entry_at(i)->is_secondary_entry()) {
      st->print_cr(" secondary entry?");
      return false;
    }
    i = cache->entry_at(i)->constant_pool_index();
    goto check_cp_index;
  }
  st->print_cr(" not in CP[*]?", i);
  return false;
}

D
duke 已提交
290
void BytecodePrinter::print_constant(int i, outputStream* st) {
291
  int orig_i = i;
292
  if (!check_index(orig_i, i, st))  return;
293

D
duke 已提交
294 295 296 297 298 299 300 301 302 303 304 305
  constantPoolOop constants = method()->constants();
  constantTag tag = constants->tag_at(i);

  if (tag.is_int()) {
    st->print_cr(" " INT32_FORMAT, constants->int_at(i));
  } else if (tag.is_long()) {
    st->print_cr(" " INT64_FORMAT, constants->long_at(i));
  } else if (tag.is_float()) {
    st->print_cr(" %f", constants->float_at(i));
  } else if (tag.is_double()) {
    st->print_cr(" %f", constants->double_at(i));
  } else if (tag.is_string()) {
306
    oop string = constants->pseudo_string_at(i);
D
duke 已提交
307 308
    print_oop(string, st);
  } else if (tag.is_unresolved_string()) {
309 310
    const char* string = constants->string_at_noresolve(i);
    st->print_cr(" %s", string);
D
duke 已提交
311 312 313 314
  } else if (tag.is_klass()) {
    st->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name());
  } else if (tag.is_unresolved_klass()) {
    st->print_cr(" <unresolved klass at %d>", i);
315
  } else if (tag.is_object()) {
316 317 318 319 320
    st->print(" <Object>");
    print_oop(constants->object_at(i), st);
  } else if (tag.is_method_type()) {
    int i2 = constants->method_type_index_at(i);
    st->print(" <MethodType> %d", i2);
321
    print_symbol(constants->symbol_at(i2), st);
322 323 324 325 326
  } else if (tag.is_method_handle()) {
    int kind = constants->method_handle_ref_kind_at(i);
    int i2 = constants->method_handle_index_at(i);
    st->print(" <MethodHandle of kind %d>", kind, i2);
    print_field_or_method(-i, i2, st);
327 328 329 330 331 332 333
  } else {
    st->print_cr(" bad tag=%d at %d", tag.value(), i);
  }
}

void BytecodePrinter::print_field_or_method(int i, outputStream* st) {
  int orig_i = i;
334
  if (!check_index(orig_i, i, st))  return;
335 336
  print_field_or_method(orig_i, i, st);
}
337

338
void BytecodePrinter::print_field_or_method(int orig_i, int i, outputStream* st) {
339 340 341
  constantPoolOop constants = method()->constants();
  constantTag tag = constants->tag_at(i);

342
  bool has_klass = true;
343

344 345 346 347
  switch (tag.value()) {
  case JVM_CONSTANT_InterfaceMethodref:
  case JVM_CONSTANT_Methodref:
  case JVM_CONSTANT_Fieldref:
348
    break;
349
  case JVM_CONSTANT_NameAndType:
350 351
  case JVM_CONSTANT_InvokeDynamic:
    has_klass = false;
352 353 354 355 356 357
    break;
  default:
    st->print_cr(" bad tag=%d at %d", tag.value(), i);
    return;
  }

358 359
  Symbol* name = constants->uncached_name_ref_at(i);
  Symbol* signature = constants->uncached_signature_ref_at(i);
360
  const char* sep = (tag.is_field() ? "/" : "");
361
  if (has_klass) {
362
    Symbol* klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i));
363 364 365 366 367 368 369 370
    st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string());
  } else {
    if (tag.is_invoke_dynamic()) {
      int bsm = constants->invoke_dynamic_bootstrap_method_ref_index_at(i);
      st->print(" bsm=%d", bsm);
    }
    st->print_cr(" %d <%s%s%s>", i, name->as_C_string(), sep, signature->as_C_string());
  }
D
duke 已提交
371 372 373
}


374
void BytecodePrinter::print_attributes(int bci, outputStream* st) {
D
duke 已提交
375
  // Show attributes of pre-rewritten codes
376
  Bytecodes::Code code = Bytecodes::java_code(raw_code());
D
duke 已提交
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
  // If the code doesn't have any fields there's nothing to print.
  // note this is ==1 because the tableswitch and lookupswitch are
  // zero size (for some reason) and we want to print stuff out for them.
  if (Bytecodes::length_for(code) == 1) {
    st->cr();
    return;
  }

  switch(code) {
    // Java specific bytecodes only matter.
    case Bytecodes::_bipush:
      st->print_cr(" " INT32_FORMAT, get_byte());
      break;
    case Bytecodes::_sipush:
      st->print_cr(" " INT32_FORMAT, get_short());
      break;
    case Bytecodes::_ldc:
394 395 396 397 398
      if (Bytecodes::uses_cp_cache(raw_code())) {
        print_constant(get_index_u1_cpcache(), st);
      } else {
        print_constant(get_index_u1(), st);
      }
D
duke 已提交
399 400 401 402
      break;

    case Bytecodes::_ldc_w:
    case Bytecodes::_ldc2_w:
403 404 405 406 407
      if (Bytecodes::uses_cp_cache(raw_code())) {
        print_constant(get_index_u2_cpcache(), st);
      } else {
        print_constant(get_index_u2(), st);
      }
D
duke 已提交
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
      break;

    case Bytecodes::_iload:
    case Bytecodes::_lload:
    case Bytecodes::_fload:
    case Bytecodes::_dload:
    case Bytecodes::_aload:
    case Bytecodes::_istore:
    case Bytecodes::_lstore:
    case Bytecodes::_fstore:
    case Bytecodes::_dstore:
    case Bytecodes::_astore:
      st->print_cr(" #%d", get_index_special());
      break;

    case Bytecodes::_iinc:
      { int index = get_index_special();
        jint offset = is_wide() ? get_short(): get_byte();
        st->print_cr(" #%d " INT32_FORMAT, index, offset);
      }
      break;

    case Bytecodes::_newarray: {
431
        BasicType atype = (BasicType)get_index_u1();
D
duke 已提交
432 433 434 435 436 437 438 439
        const char* str = type2name(atype);
        if (str == NULL || atype == T_OBJECT || atype == T_ARRAY) {
          assert(false, "Unidentified basic type");
        }
        st->print_cr(" %s", str);
      }
      break;
    case Bytecodes::_anewarray: {
440
        int klass_index = get_index_u2();
D
duke 已提交
441
        constantPoolOop constants = method()->constants();
442
        Symbol* name = constants->klass_name_at(klass_index);
D
duke 已提交
443 444 445 446
        st->print_cr(" %s ", name->as_C_string());
      }
      break;
    case Bytecodes::_multianewarray: {
447 448
        int klass_index = get_index_u2();
        int nof_dims = get_index_u1();
D
duke 已提交
449
        constantPoolOop constants = method()->constants();
450
        Symbol* name = constants->klass_name_at(klass_index);
D
duke 已提交
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
        st->print_cr(" %s %d", name->as_C_string(), nof_dims);
      }
      break;

    case Bytecodes::_ifeq:
    case Bytecodes::_ifnull:
    case Bytecodes::_iflt:
    case Bytecodes::_ifle:
    case Bytecodes::_ifne:
    case Bytecodes::_ifnonnull:
    case Bytecodes::_ifgt:
    case Bytecodes::_ifge:
    case Bytecodes::_if_icmpeq:
    case Bytecodes::_if_icmpne:
    case Bytecodes::_if_icmplt:
    case Bytecodes::_if_icmpgt:
    case Bytecodes::_if_icmple:
    case Bytecodes::_if_icmpge:
    case Bytecodes::_if_acmpeq:
    case Bytecodes::_if_acmpne:
    case Bytecodes::_goto:
    case Bytecodes::_jsr:
      st->print_cr(" %d", bci + get_short());
      break;

    case Bytecodes::_goto_w:
    case Bytecodes::_jsr_w:
      st->print_cr(" %d", bci + get_int());
      break;

    case Bytecodes::_ret: st->print_cr(" %d", get_index_special()); break;

    case Bytecodes::_tableswitch:
      { align();
        int  default_dest = bci + get_int();
        int  lo           = get_int();
        int  hi           = get_int();
        int  len          = hi - lo + 1;
        jint* dest        = NEW_RESOURCE_ARRAY(jint, len);
        for (int i = 0; i < len; i++) {
          dest[i] = bci + get_int();
        }
        st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ",
                      default_dest, lo, hi);
        int first = true;
        for (int ll = lo; ll <= hi; ll++, first = false)  {
          int idx = ll - lo;
          const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" :
                                       ", %d:" INT32_FORMAT " (delta: %d)";
          st->print(format, ll, dest[idx], dest[idx]-bci);
        }
        st->cr();
      }
      break;
    case Bytecodes::_lookupswitch:
      { align();
        int  default_dest = bci + get_int();
        int  len          = get_int();
        jint* key         = NEW_RESOURCE_ARRAY(jint, len);
        jint* dest        = NEW_RESOURCE_ARRAY(jint, len);
        for (int i = 0; i < len; i++) {
          key [i] = get_int();
          dest[i] = bci + get_int();
        };
        st->print(" %d %d ", default_dest, len);
        bool first = true;
        for (int ll = 0; ll < len; ll++, first = false)  {
          const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT :
                                       ", " INT32_FORMAT ":" INT32_FORMAT ;
          st->print(format, key[ll], dest[ll]);
        }
        st->cr();
      }
      break;

    case Bytecodes::_putstatic:
    case Bytecodes::_getstatic:
    case Bytecodes::_putfield:
529
    case Bytecodes::_getfield:
530
      print_field_or_method(get_index_u2_cpcache(), st);
D
duke 已提交
531 532 533 534 535
      break;

    case Bytecodes::_invokevirtual:
    case Bytecodes::_invokespecial:
    case Bytecodes::_invokestatic:
536
      print_field_or_method(get_index_u2_cpcache(), st);
D
duke 已提交
537 538 539
      break;

    case Bytecodes::_invokeinterface:
540 541 542
      { int i = get_index_u2_cpcache();
        int n = get_index_u1();
        get_byte();            // ignore zero byte
543
        print_field_or_method(i, st);
D
duke 已提交
544 545 546
      }
      break;

547
    case Bytecodes::_invokedynamic:
548
      print_field_or_method(get_index_u4(), st);
549 550
      break;

D
duke 已提交
551 552 553
    case Bytecodes::_new:
    case Bytecodes::_checkcast:
    case Bytecodes::_instanceof:
554
      { int i = get_index_u2();
D
duke 已提交
555
        constantPoolOop constants = method()->constants();
556
        Symbol* name = constants->klass_name_at(i);
D
duke 已提交
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
        st->print_cr(" %d <%s>", i, name->as_C_string());
      }
      break;

    case Bytecodes::_wide:
      // length is zero not one, but printed with no more info.
      break;

    default:
      ShouldNotReachHere();
      break;
  }
}


void BytecodePrinter::bytecode_epilog(int bci, outputStream* st) {
  methodDataOop mdo = method()->method_data();
  if (mdo != NULL) {
    ProfileData* data = mdo->bci_to_data(bci);
    if (data != NULL) {
      st->print("  %d", mdo->dp_to_di(data->dp()));
      st->fill_to(6);
      data->print_data_on(st);
    }
  }
}
#endif // PRODUCT