1 /*
   2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "code/codeCache.hpp"
  28 #include "code/icBuffer.hpp"
  29 #include "code/nmethod.hpp"
  30 #include "code/vtableStubs.hpp"
  31 #include "compiler/compileBroker.hpp"
  32 #include "compiler/disassembler.hpp"
  33 #include "gc_implementation/shared/markSweep.hpp"
  34 #include "gc_interface/collectedHeap.hpp"
  35 #include "interpreter/bytecodeHistogram.hpp"
  36 #include "interpreter/interpreter.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "memory/universe.hpp"
  39 #include "oops/oop.inline.hpp"
  40 #include "prims/privilegedStack.hpp"
  41 #include "runtime/arguments.hpp"
  42 #include "runtime/frame.hpp"
  43 #include "runtime/java.hpp"
  44 #include "runtime/sharedRuntime.hpp"
  45 #include "runtime/stubCodeGenerator.hpp"
  46 #include "runtime/stubRoutines.hpp"
  47 #include "runtime/vframe.hpp"
  48 #include "services/heapDumper.hpp"
  49 #include "utilities/defaultStream.hpp"
  50 #include "utilities/events.hpp"
  51 #include "utilities/top.hpp"
  52 #include "utilities/vmError.hpp"
  53 #ifdef TARGET_OS_FAMILY_linux
  54 # include "os_linux.inline.hpp"
  55 # include "thread_linux.inline.hpp"
  56 #endif
  57 #ifdef TARGET_OS_FAMILY_solaris
  58 # include "os_solaris.inline.hpp"
  59 # include "thread_solaris.inline.hpp"
  60 #endif
  61 #ifdef TARGET_OS_FAMILY_windows
  62 # include "os_windows.inline.hpp"
  63 # include "thread_windows.inline.hpp"
  64 #endif
  65 #ifdef TARGET_OS_FAMILY_bsd
  66 # include "os_bsd.inline.hpp"
  67 # include "thread_bsd.inline.hpp"
  68 #endif
  69 
  70 #ifndef ASSERT
  71 #  ifdef _DEBUG
  72    // NOTE: don't turn the lines below into a comment -- if you're getting
  73    // a compile error here, change the settings to define ASSERT
  74    ASSERT should be defined when _DEBUG is defined.  It is not intended to be used for debugging
  75    functions that do not slow down the system too much and thus can be left in optimized code.
  76    On the other hand, the code should not be included in a production version.
  77 #  endif // _DEBUG
  78 #endif // ASSERT
  79 
  80 
  81 #ifdef _DEBUG
  82 #  ifndef ASSERT
  83      configuration error: ASSERT must be defined in debug version
  84 #  endif // ASSERT
  85 #endif // _DEBUG
  86 
  87 
  88 #ifdef PRODUCT
  89 #  if -defined _DEBUG || -defined ASSERT
  90      configuration error: ASSERT et al. must not be defined in PRODUCT version
  91 #  endif
  92 #endif // PRODUCT
  93 
  94 FormatBufferResource::FormatBufferResource(const char * format, ...)
  95   : FormatBufferBase((char*)resource_allocate_bytes(RES_BUFSZ)) {
  96   va_list argp;
  97   va_start(argp, format);
  98   jio_vsnprintf(_buf, RES_BUFSZ, format, argp);
  99   va_end(argp);
 100 }
 101 
 102 void warning(const char* format, ...) {
 103   if (PrintWarnings) {
 104     FILE* const err = defaultStream::error_stream();
 105     jio_fprintf(err, "%s warning: ", VM_Version::vm_name());
 106     va_list ap;
 107     va_start(ap, format);
 108     vfprintf(err, format, ap);
 109     va_end(ap);
 110     fputc('\n', err);
 111   }
 112   if (BreakAtWarning) BREAKPOINT;
 113 }
 114 
 115 #ifndef PRODUCT
 116 
 117 #define is_token_break(ch) (isspace(ch) || (ch) == ',')
 118 
 119 static const char* last_file_name = NULL;
 120 static int         last_line_no   = -1;
 121 
 122 // assert/guarantee/... may happen very early during VM initialization.
 123 // Don't rely on anything that is initialized by Threads::create_vm(). For
 124 // example, don't use tty.
 125 bool error_is_suppressed(const char* file_name, int line_no) {
 126   // The following 1-element cache requires that passed-in
 127   // file names are always only constant literals.
 128   if (file_name == last_file_name && line_no == last_line_no)  return true;
 129 
 130   int file_name_len = (int)strlen(file_name);
 131   char separator = os::file_separator()[0];
 132   const char* base_name = strrchr(file_name, separator);
 133   if (base_name == NULL)
 134     base_name = file_name;
 135 
 136   // scan the SuppressErrorAt option
 137   const char* cp = SuppressErrorAt;
 138   for (;;) {
 139     const char* sfile;
 140     int sfile_len;
 141     int sline;
 142     bool noisy;
 143     while ((*cp) != '\0' && is_token_break(*cp))  cp++;
 144     if ((*cp) == '\0')  break;
 145     sfile = cp;
 146     while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':')  cp++;
 147     sfile_len = cp - sfile;
 148     if ((*cp) == ':')  cp++;
 149     sline = 0;
 150     while ((*cp) != '\0' && isdigit(*cp)) {
 151       sline *= 10;
 152       sline += (*cp) - '0';
 153       cp++;
 154     }
 155     // "file:line!" means the assert suppression is not silent
 156     noisy = ((*cp) == '!');
 157     while ((*cp) != '\0' && !is_token_break(*cp))  cp++;
 158     // match the line
 159     if (sline != 0) {
 160       if (sline != line_no)  continue;
 161     }
 162     // match the file
 163     if (sfile_len > 0) {
 164       const char* look = file_name;
 165       const char* look_max = file_name + file_name_len - sfile_len;
 166       const char* foundp;
 167       bool match = false;
 168       while (!match
 169              && (foundp = strchr(look, sfile[0])) != NULL
 170              && foundp <= look_max) {
 171         match = true;
 172         for (int i = 1; i < sfile_len; i++) {
 173           if (sfile[i] != foundp[i]) {
 174             match = false;
 175             break;
 176           }
 177         }
 178         look = foundp + 1;
 179       }
 180       if (!match)  continue;
 181     }
 182     // got a match!
 183     if (noisy) {
 184       fdStream out(defaultStream::output_fd());
 185       out.print_raw("[error suppressed at ");
 186       out.print_raw(base_name);
 187       char buf[16];
 188       jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
 189       out.print_raw_cr(buf);
 190     } else {
 191       // update 1-element cache for fast silent matches
 192       last_file_name = file_name;
 193       last_line_no   = line_no;
 194     }
 195     return true;
 196   }
 197 
 198   if (!is_error_reported()) {
 199     // print a friendly hint:
 200     fdStream out(defaultStream::output_fd());
 201     out.print_raw_cr("# To suppress the following error report, specify this argument");
 202     out.print_raw   ("# after -XX: or in .hotspotrc:  SuppressErrorAt=");
 203     out.print_raw   (base_name);
 204     char buf[16];
 205     jio_snprintf(buf, sizeof(buf), ":%d", line_no);
 206     out.print_raw_cr(buf);
 207   }
 208   return false;
 209 }
 210 
 211 #undef is_token_break
 212 
 213 #else
 214 
 215 // Place-holder for non-existent suppression check:
 216 #define error_is_suppressed(file_name, line_no) (false)
 217 
 218 #endif // !PRODUCT
 219 
 220 void report_vm_error(const char* file, int line, const char* error_msg,
 221                      const char* detail_msg)
 222 {
 223   if (Debugging || error_is_suppressed(file, line)) return;
 224   Thread* const thread = ThreadLocalStorage::get_thread_slow();
 225   VMError err(thread, file, line, error_msg, detail_msg);
 226   err.report_and_die();
 227 }
 228 
 229 void report_fatal(const char* file, int line, const char* message)
 230 {
 231   report_vm_error(file, line, "fatal error", message);
 232 }
 233 
 234 // Used by report_vm_out_of_memory to detect recursion.
 235 static jint _exiting_out_of_mem = 0;
 236 
 237 void report_vm_out_of_memory(const char* file, int line, size_t size,
 238                              const char* message) {
 239   if (Debugging) return;
 240 
 241   // We try to gather additional information for the first out of memory
 242   // error only; gathering additional data might cause an allocation and a
 243   // recursive out_of_memory condition.
 244 
 245   const jint exiting = 1;
 246   // If we succeed in changing the value, we're the first one in.
 247   bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting;
 248 
 249   if (first_time_here) {
 250     Thread* thread = ThreadLocalStorage::get_thread_slow();
 251     VMError(thread, file, line, size, message).report_and_die();
 252   }
 253 
 254   // Dump core and abort
 255   vm_abort(true);
 256 }
 257 
 258 void report_should_not_call(const char* file, int line) {
 259   report_vm_error(file, line, "ShouldNotCall()");
 260 }
 261 
 262 void report_should_not_reach_here(const char* file, int line) {
 263   report_vm_error(file, line, "ShouldNotReachHere()");
 264 }
 265 
 266 void report_should_not_reach_here2(const char* file, int line, const char* message) {
 267   report_vm_error(file, line, "ShouldNotReachHere()", message);
 268 }
 269 
 270 void report_unimplemented(const char* file, int line) {
 271   report_vm_error(file, line, "Unimplemented()");
 272 }
 273 
 274 void report_untested(const char* file, int line, const char* message) {
 275 #ifndef PRODUCT
 276   warning("Untested: %s in %s: %d\n", message, file, line);
 277 #endif // !PRODUCT
 278 }
 279 
 280 void report_out_of_shared_space(SharedSpaceType shared_space) {
 281   static const char* name[] = {
 282     "native memory for metadata",
 283     "shared read only space",
 284     "shared read write space",
 285     "shared miscellaneous data space"
 286   };
 287   static const char* flag[] = {
 288     "Metaspace",
 289     "SharedReadOnlySize",
 290     "SharedReadWriteSize",
 291     "SharedMiscDataSize"
 292   };
 293 
 294    warning("\nThe %s is not large enough\n"
 295            "to preload requested classes. Use -XX:%s=\n"
 296            "to increase the initial size of %s.\n",
 297            name[shared_space], flag[shared_space], name[shared_space]);
 298    exit(2);
 299 }
 300 
 301 void report_java_out_of_memory(const char* message) {
 302   static jint out_of_memory_reported = 0;
 303 
 304   // A number of threads may attempt to report OutOfMemoryError at around the
 305   // same time. To avoid dumping the heap or executing the data collection
 306   // commands multiple times we just do it once when the first threads reports
 307   // the error.
 308   if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
 309     // create heap dump before OnOutOfMemoryError commands are executed
 310     if (HeapDumpOnOutOfMemoryError) {
 311       tty->print_cr("java.lang.OutOfMemoryError: %s", message);
 312       HeapDumper::dump_heap_from_oome();
 313     }
 314 
 315     if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
 316       VMError err(message);
 317       err.report_java_out_of_memory();
 318     }
 319   }
 320 }
 321 
 322 static bool error_reported = false;
 323 
 324 // call this when the VM is dying--it might loosen some asserts
 325 void set_error_reported() {
 326   error_reported = true;
 327 }
 328 
 329 bool is_error_reported() {
 330     return error_reported;
 331 }
 332 
 333 #ifndef PRODUCT
 334 #include <signal.h>
 335 
 336 void test_error_handler(size_t test_num)
 337 {
 338   if (test_num == 0) return;
 339 
 340   // If asserts are disabled, use the corresponding guarantee instead.
 341   size_t n = test_num;
 342   NOT_DEBUG(if (n <= 2) n += 2);
 343 
 344   const char* const str = "hello";
 345   const size_t      num = (size_t)os::vm_page_size();
 346 
 347   const char* const eol = os::line_separator();
 348   const char* const msg = "this message should be truncated during formatting";
 349 
 350   // Keep this in sync with test/runtime/6888954/vmerrors.sh.
 351   switch (n) {
 352     case  1: assert(str == NULL, "expected null");
 353     case  2: assert(num == 1023 && *str == 'X',
 354                     err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 355     case  3: guarantee(str == NULL, "expected null");
 356     case  4: guarantee(num == 1023 && *str == 'X',
 357                        err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 358     case  5: fatal("expected null");
 359     case  6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 360     case  7: fatal(err_msg("%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 361                            "%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 362                            "%s%s#    %s%s#    %s%s#    %s%s#    %s",
 363                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 364                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 365                            msg, eol, msg, eol, msg, eol, msg, eol, msg));
 366     case  8: vm_exit_out_of_memory(num, "ChunkPool::allocate");
 367     case  9: ShouldNotCallThis();
 368     case 10: ShouldNotReachHere();
 369     case 11: Unimplemented();
 370     // This is last because it does not generate an hs_err* file on Windows.
 371     case 12: os::signal_raise(SIGSEGV);
 372 
 373     default: ShouldNotReachHere();
 374   }
 375 }
 376 #endif // !PRODUCT
 377 
 378 // ------ helper functions for debugging go here ------------
 379 
 380 // All debug entries should be wrapped with a stack allocated
 381 // Command object. It makes sure a resource mark is set and
 382 // flushes the logfile to prevent file sharing problems.
 383 
 384 class Command : public StackObj {
 385  private:
 386   ResourceMark rm;
 387   ResetNoHandleMark rnhm;
 388   HandleMark   hm;
 389   bool debug_save;
 390  public:
 391   static int level;
 392   Command(const char* str) {
 393     debug_save = Debugging;
 394     Debugging = true;
 395     if (level++ > 0)  return;
 396     tty->cr();
 397     tty->print_cr("\"Executing %s\"", str);
 398   }
 399 
 400   ~Command() {
 401         tty->flush();
 402         Debugging = debug_save;
 403         level--;
 404   }
 405 };
 406 
 407 int Command::level = 0;
 408 
 409 #ifndef PRODUCT
 410 
 411 extern "C" void blob(CodeBlob* cb) {
 412   Command c("blob");
 413   cb->print();
 414 }
 415 
 416 
 417 extern "C" void dump_vtable(address p) {
 418   Command c("dump_vtable");
 419   Klass* k = (Klass*)p;
 420   InstanceKlass::cast(k)->vtable()->print();
 421 }
 422 
 423 
 424 extern "C" void nm(intptr_t p) {
 425   // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
 426   Command c("nm");
 427   CodeBlob* cb = CodeCache::find_blob((address)p);
 428   if (cb == NULL) {
 429     tty->print_cr("NULL");
 430   } else {
 431     cb->print();
 432   }
 433 }
 434 
 435 
 436 extern "C" void disnm(intptr_t p) {
 437   Command c("disnm");
 438   CodeBlob* cb = CodeCache::find_blob((address) p);
 439   nmethod* nm = cb->as_nmethod_or_null();
 440   if (nm) {
 441     nm->print();
 442     Disassembler::decode(nm);
 443   } else {
 444     cb->print();
 445     Disassembler::decode(cb);
 446   }
 447 }
 448 
 449 
 450 extern "C" void printnm(intptr_t p) {
 451   char buffer[256];
 452   sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
 453   Command c(buffer);
 454   CodeBlob* cb = CodeCache::find_blob((address) p);
 455   if (cb->is_nmethod()) {
 456     nmethod* nm = (nmethod*)cb;
 457     nm->print_nmethod(true);
 458   }
 459 }
 460 
 461 
 462 extern "C" void universe() {
 463   Command c("universe");
 464   Universe::print();
 465 }
 466 
 467 
 468 extern "C" void verify() {
 469   // try to run a verify on the entire system
 470   // note: this may not be safe if we're not at a safepoint; for debugging,
 471   // this manipulates the safepoint settings to avoid assertion failures
 472   Command c("universe verify");
 473   bool safe = SafepointSynchronize::is_at_safepoint();
 474   if (!safe) {
 475     tty->print_cr("warning: not at safepoint -- verify may fail");
 476     SafepointSynchronize::set_is_at_safepoint();
 477   }
 478   // Ensure Eden top is correct before verification
 479   Universe::heap()->prepare_for_verify();
 480   Universe::verify();
 481   if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
 482 }
 483 
 484 
 485 extern "C" void pp(void* p) {
 486   Command c("pp");
 487   FlagSetting fl(PrintVMMessages, true);
 488   FlagSetting f2(DisplayVMOutput, true);
 489   if (Universe::heap()->is_in(p)) {
 490     oop obj = oop(p);
 491     obj->print();
 492   } else {
 493     tty->print(PTR_FORMAT, p);
 494   }
 495 }
 496 
 497 
 498 // pv: print vm-printable object
 499 extern "C" void pa(intptr_t p)   { ((AllocatedObj*) p)->print(); }
 500 extern "C" void findpc(intptr_t x);
 501 
 502 #endif // !PRODUCT
 503 
 504 extern "C" void ps() { // print stack
 505   if (Thread::current() == NULL) return;
 506   Command c("ps");
 507 
 508 
 509   // Prints the stack of the current Java thread
 510   JavaThread* p = JavaThread::active();
 511   tty->print(" for thread: ");
 512   p->print();
 513   tty->cr();
 514 
 515   if (p->has_last_Java_frame()) {
 516     // If the last_Java_fp is set we are in C land and
 517     // can call the standard stack_trace function.
 518 #ifdef PRODUCT
 519     p->print_stack();
 520   } else {
 521     tty->print_cr("Cannot find the last Java frame, printing stack disabled.");
 522 #else // !PRODUCT
 523     p->trace_stack();
 524   } else {
 525     frame f = os::current_frame();
 526     RegisterMap reg_map(p);
 527     f = f.sender(&reg_map);
 528     tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
 529     p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
 530   pd_ps(f);
 531 #endif // PRODUCT
 532   }
 533 
 534 }
 535 
 536 extern "C" void pfl() {
 537   // print frame layout
 538   Command c("pfl");
 539   JavaThread* p = JavaThread::active();
 540   tty->print(" for thread: ");
 541   p->print();
 542   tty->cr();
 543   if (p->has_last_Java_frame()) {
 544     p->print_frame_layout();
 545   }
 546 }
 547 
 548 #ifndef PRODUCT
 549 
 550 extern "C" void psf() { // print stack frames
 551   {
 552     Command c("psf");
 553     JavaThread* p = JavaThread::active();
 554     tty->print(" for thread: ");
 555     p->print();
 556     tty->cr();
 557     if (p->has_last_Java_frame()) {
 558       p->trace_frames();
 559     }
 560   }
 561 }
 562 
 563 
 564 extern "C" void threads() {
 565   Command c("threads");
 566   Threads::print(false, true);
 567 }
 568 
 569 
 570 extern "C" void psd() {
 571   Command c("psd");
 572   SystemDictionary::print();
 573 }
 574 
 575 
 576 extern "C" void safepoints() {
 577   Command c("safepoints");
 578   SafepointSynchronize::print_state();
 579 }
 580 
 581 #endif // !PRODUCT
 582 
 583 extern "C" void pss() { // print all stacks
 584   if (Thread::current() == NULL) return;
 585   Command c("pss");
 586   Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
 587 }
 588 
 589 #ifndef PRODUCT
 590 
 591 extern "C" void debug() {               // to set things up for compiler debugging
 592   Command c("debug");
 593   WizardMode = true;
 594   PrintVMMessages = PrintCompilation = true;
 595   PrintInlining = PrintAssembly = true;
 596   tty->flush();
 597 }
 598 
 599 
 600 extern "C" void ndebug() {              // undo debug()
 601   Command c("ndebug");
 602   PrintCompilation = false;
 603   PrintInlining = PrintAssembly = false;
 604   tty->flush();
 605 }
 606 
 607 
 608 extern "C" void flush()  {
 609   Command c("flush");
 610   tty->flush();
 611 }
 612 
 613 extern "C" void events() {
 614   Command c("events");
 615   Events::print();
 616 }
 617 
 618 // Given a heap address that was valid before the most recent GC, if
 619 // the oop that used to contain it is still live, prints the new
 620 // location of the oop and the address. Useful for tracking down
 621 // certain kinds of naked oop and oop map bugs.
 622 extern "C" void pnl(intptr_t old_heap_addr) {
 623   // Print New Location of old heap address
 624   Command c("pnl");
 625 #ifndef VALIDATE_MARK_SWEEP
 626   tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled");
 627 #else
 628   MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr);
 629 #endif
 630 }
 631 
 632 
 633 extern "C" Method* findm(intptr_t pc) {
 634   Command c("findm");
 635   nmethod* nm = CodeCache::find_nmethod((address)pc);
 636   return (nm == NULL) ? (Method*)NULL : nm->method();
 637 }
 638 
 639 
 640 extern "C" nmethod* findnm(intptr_t addr) {
 641   Command c("findnm");
 642   return  CodeCache::find_nmethod((address)addr);
 643 }
 644 
 645 static address same_page(address x, address y) {
 646   intptr_t page_bits = -os::vm_page_size();
 647   if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) {
 648     return x;
 649   } else if (x > y) {
 650     return (address)(intptr_t(y) | ~page_bits) + 1;
 651   } else {
 652     return (address)(intptr_t(y) & page_bits);
 653   }
 654 }
 655 
 656 
 657 // Another interface that isn't ambiguous in dbx.
 658 // Can we someday rename the other find to hsfind?
 659 extern "C" void hsfind(intptr_t x) {
 660   Command c("hsfind");
 661   os::print_location(tty, x, false);
 662 }
 663 
 664 
 665 extern "C" void find(intptr_t x) {
 666   Command c("find");
 667   os::print_location(tty, x, false);
 668 }
 669 
 670 
 671 extern "C" void findpc(intptr_t x) {
 672   Command c("findpc");
 673   os::print_location(tty, x, true);
 674 }
 675 
 676 
 677 // Need method pointer to find bcp, when not in permgen.
 678 extern "C" void findbcp(intptr_t method, intptr_t bcp) {
 679   Command c("findbcp");
 680   Method* mh = (Method*)method;
 681   if (!mh->is_native()) {
 682     tty->print_cr("bci_from(%p) = %d; print_codes():",
 683                         mh, mh->bci_from(address(bcp)));
 684     mh->print_codes_on(tty);
 685   }
 686 }
 687 
 688 // int versions of all methods to avoid having to type type casts in the debugger
 689 
 690 void pp(intptr_t p)          { pp((void*)p); }
 691 void pp(oop p)               { pp((void*)p); }
 692 
 693 void help() {
 694   Command c("help");
 695   tty->print_cr("basic");
 696   tty->print_cr("  pp(void* p)   - try to make sense of p");
 697   tty->print_cr("  pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
 698   tty->print_cr("  ps()          - print current thread stack");
 699   tty->print_cr("  pss()         - print all thread stacks");
 700   tty->print_cr("  pm(int pc)    - print Method* given compiled PC");
 701   tty->print_cr("  findm(intptr_t pc) - finds Method*");
 702   tty->print_cr("  find(intptr_t x)   - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
 703 
 704   tty->print_cr("misc.");
 705   tty->print_cr("  flush()       - flushes the log file");
 706   tty->print_cr("  events()      - dump events from ring buffers");
 707 
 708 
 709   tty->print_cr("compiler debugging");
 710   tty->print_cr("  debug()       - to set things up for compiler debugging");
 711   tty->print_cr("  ndebug()      - undo debug");
 712 }
 713 
 714 #if 0
 715 
 716 // BobV's command parser for debugging on windows when nothing else works.
 717 
 718 enum CommandID {
 719   CMDID_HELP,
 720   CMDID_QUIT,
 721   CMDID_HSFIND,
 722   CMDID_PSS,
 723   CMDID_PS,
 724   CMDID_PSF,
 725   CMDID_FINDM,
 726   CMDID_FINDNM,
 727   CMDID_PP,
 728   CMDID_BPT,
 729   CMDID_EXIT,
 730   CMDID_VERIFY,
 731   CMDID_THREADS,
 732   CMDID_ILLEGAL = 99
 733 };
 734 
 735 struct CommandParser {
 736    char *name;
 737    CommandID code;
 738    char *description;
 739 };
 740 
 741 struct CommandParser CommandList[] = {
 742   (char *)"help", CMDID_HELP, "  Dump this list",
 743   (char *)"quit", CMDID_QUIT, "  Return from this routine",
 744   (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address",
 745   (char *)"ps", CMDID_PS, "    Print Current Thread Stack Trace",
 746   (char *)"pss", CMDID_PSS, "   Print All Thread Stack Trace",
 747   (char *)"psf", CMDID_PSF, "   Print All Stack Frames",
 748   (char *)"findm", CMDID_FINDM, " Find a Method* from a PC",
 749   (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC",
 750   (char *)"pp", CMDID_PP, "    Find out something about a pointer",
 751   (char *)"break", CMDID_BPT, " Execute a breakpoint",
 752   (char *)"exitvm", CMDID_EXIT, "Exit the VM",
 753   (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify",
 754   (char *)"thread", CMDID_THREADS, "Dump Info on all Threads",
 755   (char *)0, CMDID_ILLEGAL
 756 };
 757 
 758 
 759 // get_debug_command()
 760 //
 761 // Read a command from standard input.
 762 // This is useful when you have a debugger
 763 // which doesn't support calling into functions.
 764 //
 765 void get_debug_command()
 766 {
 767   ssize_t count;
 768   int i,j;
 769   bool gotcommand;
 770   intptr_t addr;
 771   char buffer[256];
 772   nmethod *nm;
 773   Method* m;
 774 
 775   tty->print_cr("You have entered the diagnostic command interpreter");
 776   tty->print("The supported commands are:\n");
 777   for ( i=0; ; i++ ) {
 778     if ( CommandList[i].code == CMDID_ILLEGAL )
 779       break;
 780     tty->print_cr("  %s \n", CommandList[i].name );
 781   }
 782 
 783   while ( 1 ) {
 784     gotcommand = false;
 785     tty->print("Please enter a command: ");
 786     count = scanf("%s", buffer) ;
 787     if ( count >=0 ) {
 788       for ( i=0; ; i++ ) {
 789         if ( CommandList[i].code == CMDID_ILLEGAL ) {
 790           if (!gotcommand) tty->print("Invalid command, please try again\n");
 791           break;
 792         }
 793         if ( strcmp(buffer, CommandList[i].name) == 0 ) {
 794           gotcommand = true;
 795           switch ( CommandList[i].code ) {
 796               case CMDID_PS:
 797                 ps();
 798                 break;
 799               case CMDID_PSS:
 800                 pss();
 801                 break;
 802               case CMDID_PSF:
 803                 psf();
 804                 break;
 805               case CMDID_FINDM:
 806                 tty->print("Please enter the hex addr to pass to findm: ");
 807                 scanf("%I64X", &addr);
 808                 m = (Method*)findm(addr);
 809                 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m);
 810                 break;
 811               case CMDID_FINDNM:
 812                 tty->print("Please enter the hex addr to pass to findnm: ");
 813                 scanf("%I64X", &addr);
 814                 nm = (nmethod*)findnm(addr);
 815                 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm);
 816                 break;
 817               case CMDID_PP:
 818                 tty->print("Please enter the hex addr to pass to pp: ");
 819                 scanf("%I64X", &addr);
 820                 pp((void*)addr);
 821                 break;
 822               case CMDID_EXIT:
 823                 exit(0);
 824               case CMDID_HELP:
 825                 tty->print("Here are the supported commands: ");
 826                 for ( j=0; ; j++ ) {
 827                   if ( CommandList[j].code == CMDID_ILLEGAL )
 828                     break;
 829                   tty->print_cr("  %s --  %s\n", CommandList[j].name,
 830                                                  CommandList[j].description );
 831                 }
 832                 break;
 833               case CMDID_QUIT:
 834                 return;
 835                 break;
 836               case CMDID_BPT:
 837                 BREAKPOINT;
 838                 break;
 839               case CMDID_VERIFY:
 840                 verify();;
 841                 break;
 842               case CMDID_THREADS:
 843                 threads();;
 844                 break;
 845               case CMDID_HSFIND:
 846                 tty->print("Please enter the hex addr to pass to hsfind: ");
 847                 scanf("%I64X", &addr);
 848                 tty->print("Calling hsfind(0x%I64X)\n", addr);
 849                 hsfind(addr);
 850                 break;
 851               default:
 852               case CMDID_ILLEGAL:
 853                 break;
 854           }
 855         }
 856       }
 857     }
 858   }
 859 }
 860 #endif
 861 
 862 #endif // !PRODUCT