1 /*
   2  * Copyright (c) 1997, 2014, 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 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  92 
  93 FormatBufferResource::FormatBufferResource(const char * format, ...)
  94   : FormatBufferBase((char*)resource_allocate_bytes(RES_BUFSZ)) {
  95   va_list argp;
  96   va_start(argp, format);
  97   jio_vsnprintf(_buf, RES_BUFSZ, format, argp);
  98   va_end(argp);
  99 }
 100 
 101 ATTRIBUTE_PRINTF(1, 2)
 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 void report_vm_out_of_memory(const char* file, int line, size_t size,
 235                              VMErrorType vm_err_type, const char* message) {
 236   if (Debugging) return;
 237 
 238   Thread* thread = ThreadLocalStorage::get_thread_slow();
 239   VMError(thread, file, line, size, vm_err_type, message).report_and_die();
 240 
 241   // The UseOSErrorReporting option in report_and_die() may allow a return
 242   // to here. 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_unimplemented(const char* file, int line) {
 255   report_vm_error(file, line, "Unimplemented()");
 256 }
 257 
 258 void report_untested(const char* file, int line, const char* message) {
 259 #ifndef PRODUCT
 260   warning("Untested: %s in %s: %d\n", message, file, line);
 261 #endif // !PRODUCT
 262 }
 263 
 264 void report_out_of_shared_space(SharedSpaceType shared_space) {
 265   static const char* name[] = {
 266     "native memory for metadata",
 267     "shared read only space",
 268     "shared read write space",
 269     "shared miscellaneous data space"
 270   };
 271   static const char* flag[] = {
 272     "Metaspace",
 273     "SharedReadOnlySize",
 274     "SharedReadWriteSize",
 275     "SharedMiscDataSize"
 276   };
 277 
 278    warning("\nThe %s is not large enough\n"
 279            "to preload requested classes. Use -XX:%s=\n"
 280            "to increase the initial size of %s.\n",
 281            name[shared_space], flag[shared_space], name[shared_space]);
 282    exit(2);
 283 }
 284 
 285 void report_java_out_of_memory(const char* message) {
 286   static jint out_of_memory_reported = 0;
 287 
 288   // A number of threads may attempt to report OutOfMemoryError at around the
 289   // same time. To avoid dumping the heap or executing the data collection
 290   // commands multiple times we just do it once when the first threads reports
 291   // the error.
 292   if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
 293     // create heap dump before OnOutOfMemoryError commands are executed
 294     if (HeapDumpOnOutOfMemoryError) {
 295       tty->print_cr("java.lang.OutOfMemoryError: %s", message);
 296       HeapDumper::dump_heap_from_oome();
 297     }
 298 
 299     if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
 300       VMError err(message);
 301       err.report_java_out_of_memory();
 302     }
 303   }
 304 }
 305 
 306 static bool error_reported = false;
 307 
 308 // call this when the VM is dying--it might loosen some asserts
 309 void set_error_reported() {
 310   error_reported = true;
 311 }
 312 
 313 bool is_error_reported() {
 314     return error_reported;
 315 }
 316 
 317 #ifndef PRODUCT
 318 #include <signal.h>
 319 
 320 void test_error_handler() {
 321   uintx test_num = ErrorHandlerTest;
 322   if (test_num == 0) return;
 323 
 324   // If asserts are disabled, use the corresponding guarantee instead.
 325   size_t n = test_num;
 326   NOT_DEBUG(if (n <= 2) n += 2);
 327 
 328   const char* const str = "hello";
 329   const size_t      num = (size_t)os::vm_page_size();
 330 
 331   const char* const eol = os::line_separator();
 332   const char* const msg = "this message should be truncated during formatting";
 333   char * const dataPtr = NULL;  // bad data pointer
 334   const void (*funcPtr)(void) = (const void(*)()) 0xF;  // bad function pointer
 335 
 336   // Keep this in sync with test/runtime/6888954/vmerrors.sh.
 337   switch (n) {
 338     case  1: assert(str == NULL, "expected null");
 339     case  2: assert(num == 1023 && *str == 'X',
 340                     err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 341     case  3: guarantee(str == NULL, "expected null");
 342     case  4: guarantee(num == 1023 && *str == 'X',
 343                        err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 344     case  5: fatal("expected null");
 345     case  6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 346     case  7: fatal(err_msg("%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 347                            "%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 348                            "%s%s#    %s%s#    %s%s#    %s%s#    %s",
 349                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 350                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 351                            msg, eol, msg, eol, msg, eol, msg, eol, msg));
 352     case  8: vm_exit_out_of_memory(num, OOM_MALLOC_ERROR, "ChunkPool::allocate");
 353     case  9: ShouldNotCallThis();
 354     case 10: ShouldNotReachHere();
 355     case 11: Unimplemented();
 356     // There's no guarantee the bad data pointer will crash us
 357     // so "break" out to the ShouldNotReachHere().
 358     case 12: *dataPtr = '\0'; break;
 359     // There's no guarantee the bad function pointer will crash us
 360     // so "break" out to the ShouldNotReachHere().
 361     case 13: (*funcPtr)(); break;
 362 
 363     default: tty->print_cr("ERROR: %d: unexpected test_num value.", n);
 364   }
 365   ShouldNotReachHere();
 366 }
 367 #endif // !PRODUCT
 368 
 369 // ------ helper functions for debugging go here ------------
 370 
 371 // All debug entries should be wrapped with a stack allocated
 372 // Command object. It makes sure a resource mark is set and
 373 // flushes the logfile to prevent file sharing problems.
 374 
 375 class Command : public StackObj {
 376  private:
 377   ResourceMark rm;
 378   ResetNoHandleMark rnhm;
 379   HandleMark   hm;
 380   bool debug_save;
 381  public:
 382   static int level;
 383   Command(const char* str) {
 384     debug_save = Debugging;
 385     Debugging = true;
 386     if (level++ > 0)  return;
 387     tty->cr();
 388     tty->print_cr("\"Executing %s\"", str);
 389   }
 390 
 391   ~Command() {
 392         tty->flush();
 393         Debugging = debug_save;
 394         level--;
 395   }
 396 };
 397 
 398 int Command::level = 0;
 399 
 400 #ifndef PRODUCT
 401 
 402 extern "C" void blob(CodeBlob* cb) {
 403   Command c("blob");
 404   cb->print();
 405 }
 406 
 407 
 408 extern "C" void dump_vtable(address p) {
 409   Command c("dump_vtable");
 410   Klass* k = (Klass*)p;
 411   InstanceKlass::cast(k)->vtable()->print();
 412 }
 413 
 414 
 415 extern "C" void nm(intptr_t p) {
 416   // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
 417   Command c("nm");
 418   CodeBlob* cb = CodeCache::find_blob((address)p);
 419   if (cb == NULL) {
 420     tty->print_cr("NULL");
 421   } else {
 422     cb->print();
 423   }
 424 }
 425 
 426 
 427 extern "C" void disnm(intptr_t p) {
 428   Command c("disnm");
 429   CodeBlob* cb = CodeCache::find_blob((address) p);
 430   nmethod* nm = cb->as_nmethod_or_null();
 431   if (nm) {
 432     nm->print();
 433     Disassembler::decode(nm);
 434   } else {
 435     cb->print();
 436     Disassembler::decode(cb);
 437   }
 438 }
 439 
 440 
 441 extern "C" void printnm(intptr_t p) {
 442   char buffer[256];
 443   sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
 444   Command c(buffer);
 445   CodeBlob* cb = CodeCache::find_blob((address) p);
 446   if (cb->is_nmethod()) {
 447     nmethod* nm = (nmethod*)cb;
 448     nm->print_nmethod(true);
 449   }
 450 }
 451 
 452 
 453 extern "C" void universe() {
 454   Command c("universe");
 455   Universe::print();
 456 }
 457 
 458 
 459 extern "C" void verify() {
 460   // try to run a verify on the entire system
 461   // note: this may not be safe if we're not at a safepoint; for debugging,
 462   // this manipulates the safepoint settings to avoid assertion failures
 463   Command c("universe verify");
 464   bool safe = SafepointSynchronize::is_at_safepoint();
 465   if (!safe) {
 466     tty->print_cr("warning: not at safepoint -- verify may fail");
 467     SafepointSynchronize::set_is_at_safepoint();
 468   }
 469   // Ensure Eden top is correct before verification
 470   Universe::heap()->prepare_for_verify();
 471   Universe::verify();
 472   if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
 473 }
 474 
 475 
 476 extern "C" void pp(void* p) {
 477   Command c("pp");
 478   FlagSetting fl(PrintVMMessages, true);
 479   FlagSetting f2(DisplayVMOutput, true);
 480   if (Universe::heap()->is_in(p)) {
 481     oop obj = oop(p);
 482     obj->print();
 483   } else {
 484     tty->print(PTR_FORMAT, p);
 485   }
 486 }
 487 
 488 
 489 // pv: print vm-printable object
 490 extern "C" void pa(intptr_t p)   { ((AllocatedObj*) p)->print(); }
 491 extern "C" void findpc(intptr_t x);
 492 
 493 #endif // !PRODUCT
 494 
 495 extern "C" void ps() { // print stack
 496   if (Thread::current() == NULL) return;
 497   Command c("ps");
 498 
 499 
 500   // Prints the stack of the current Java thread
 501   JavaThread* p = JavaThread::active();
 502   tty->print(" for thread: ");
 503   p->print();
 504   tty->cr();
 505 
 506   if (p->has_last_Java_frame()) {
 507     // If the last_Java_fp is set we are in C land and
 508     // can call the standard stack_trace function.
 509 #ifdef PRODUCT
 510     p->print_stack();
 511   } else {
 512     tty->print_cr("Cannot find the last Java frame, printing stack disabled.");
 513 #else // !PRODUCT
 514     p->trace_stack();
 515   } else {
 516     frame f = os::current_frame();
 517     RegisterMap reg_map(p);
 518     f = f.sender(&reg_map);
 519     tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
 520     p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
 521   pd_ps(f);
 522 #endif // PRODUCT
 523   }
 524 
 525 }
 526 
 527 extern "C" void pfl() {
 528   // print frame layout
 529   Command c("pfl");
 530   JavaThread* p = JavaThread::active();
 531   tty->print(" for thread: ");
 532   p->print();
 533   tty->cr();
 534   if (p->has_last_Java_frame()) {
 535     p->print_frame_layout();
 536   }
 537 }
 538 
 539 #ifndef PRODUCT
 540 
 541 extern "C" void psf() { // print stack frames
 542   {
 543     Command c("psf");
 544     JavaThread* p = JavaThread::active();
 545     tty->print(" for thread: ");
 546     p->print();
 547     tty->cr();
 548     if (p->has_last_Java_frame()) {
 549       p->trace_frames();
 550     }
 551   }
 552 }
 553 
 554 
 555 extern "C" void threads() {
 556   Command c("threads");
 557   Threads::print(false, true);
 558 }
 559 
 560 
 561 extern "C" void psd() {
 562   Command c("psd");
 563   SystemDictionary::print();
 564 }
 565 
 566 
 567 extern "C" void safepoints() {
 568   Command c("safepoints");
 569   SafepointSynchronize::print_state();
 570 }
 571 
 572 #endif // !PRODUCT
 573 
 574 extern "C" void pss() { // print all stacks
 575   if (Thread::current() == NULL) return;
 576   Command c("pss");
 577   Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
 578 }
 579 
 580 #ifndef PRODUCT
 581 
 582 extern "C" void debug() {               // to set things up for compiler debugging
 583   Command c("debug");
 584   WizardMode = true;
 585   PrintVMMessages = PrintCompilation = true;
 586   PrintInlining = PrintAssembly = true;
 587   tty->flush();
 588 }
 589 
 590 
 591 extern "C" void ndebug() {              // undo debug()
 592   Command c("ndebug");
 593   PrintCompilation = false;
 594   PrintInlining = PrintAssembly = false;
 595   tty->flush();
 596 }
 597 
 598 
 599 extern "C" void flush()  {
 600   Command c("flush");
 601   tty->flush();
 602 }
 603 
 604 extern "C" void events() {
 605   Command c("events");
 606   Events::print();
 607 }
 608 
 609 extern "C" Method* findm(intptr_t pc) {
 610   Command c("findm");
 611   nmethod* nm = CodeCache::find_nmethod((address)pc);
 612   return (nm == NULL) ? (Method*)NULL : nm->method();
 613 }
 614 
 615 
 616 extern "C" nmethod* findnm(intptr_t addr) {
 617   Command c("findnm");
 618   return  CodeCache::find_nmethod((address)addr);
 619 }
 620 
 621 // Another interface that isn't ambiguous in dbx.
 622 // Can we someday rename the other find to hsfind?
 623 extern "C" void hsfind(intptr_t x) {
 624   Command c("hsfind");
 625   os::print_location(tty, x, false);
 626 }
 627 
 628 
 629 extern "C" void find(intptr_t x) {
 630   Command c("find");
 631   os::print_location(tty, x, false);
 632 }
 633 
 634 
 635 extern "C" void findpc(intptr_t x) {
 636   Command c("findpc");
 637   os::print_location(tty, x, true);
 638 }
 639 
 640 
 641 // Need method pointer to find bcp, when not in permgen.
 642 extern "C" void findbcp(intptr_t method, intptr_t bcp) {
 643   Command c("findbcp");
 644   Method* mh = (Method*)method;
 645   if (!mh->is_native()) {
 646     tty->print_cr("bci_from(%p) = %d; print_codes():",
 647                         mh, mh->bci_from(address(bcp)));
 648     mh->print_codes_on(tty);
 649   }
 650 }
 651 
 652 // int versions of all methods to avoid having to type type casts in the debugger
 653 
 654 void pp(intptr_t p)          { pp((void*)p); }
 655 void pp(oop p)               { pp((void*)p); }
 656 
 657 void help() {
 658   Command c("help");
 659   tty->print_cr("basic");
 660   tty->print_cr("  pp(void* p)   - try to make sense of p");
 661   tty->print_cr("  pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
 662   tty->print_cr("  ps()          - print current thread stack");
 663   tty->print_cr("  pss()         - print all thread stacks");
 664   tty->print_cr("  pm(int pc)    - print Method* given compiled PC");
 665   tty->print_cr("  findm(intptr_t pc) - finds Method*");
 666   tty->print_cr("  find(intptr_t x)   - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
 667 
 668   tty->print_cr("misc.");
 669   tty->print_cr("  flush()       - flushes the log file");
 670   tty->print_cr("  events()      - dump events from ring buffers");
 671 
 672 
 673   tty->print_cr("compiler debugging");
 674   tty->print_cr("  debug()       - to set things up for compiler debugging");
 675   tty->print_cr("  ndebug()      - undo debug");
 676 }
 677 
 678 #endif // !PRODUCT