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