Mon, 09 Aug 2010 17:51:56 -0700
Merge
1 /*
2 * Copyright (c) 1997, 2010, 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 */
25 # include "incls/_precompiled.incl"
26 # include "incls/_debug.cpp.incl"
28 #ifndef ASSERT
29 # ifdef _DEBUG
30 // NOTE: don't turn the lines below into a comment -- if you're getting
31 // a compile error here, change the settings to define ASSERT
32 ASSERT should be defined when _DEBUG is defined. It is not intended to be used for debugging
33 functions that do not slow down the system too much and thus can be left in optimized code.
34 On the other hand, the code should not be included in a production version.
35 # endif // _DEBUG
36 #endif // ASSERT
39 #ifdef _DEBUG
40 # ifndef ASSERT
41 configuration error: ASSERT must be defined in debug version
42 # endif // ASSERT
43 #endif // _DEBUG
46 #ifdef PRODUCT
47 # if -defined _DEBUG || -defined ASSERT
48 configuration error: ASSERT et al. must not be defined in PRODUCT version
49 # endif
50 #endif // PRODUCT
53 void warning(const char* format, ...) {
54 // In case error happens before init or during shutdown
55 if (tty == NULL) ostream_init();
57 tty->print("%s warning: ", VM_Version::vm_name());
58 va_list ap;
59 va_start(ap, format);
60 tty->vprint_cr(format, ap);
61 va_end(ap);
62 if (BreakAtWarning) BREAKPOINT;
63 }
65 #ifndef PRODUCT
67 #define is_token_break(ch) (isspace(ch) || (ch) == ',')
69 static const char* last_file_name = NULL;
70 static int last_line_no = -1;
72 // assert/guarantee/... may happen very early during VM initialization.
73 // Don't rely on anything that is initialized by Threads::create_vm(). For
74 // example, don't use tty.
75 bool error_is_suppressed(const char* file_name, int line_no) {
76 // The following 1-element cache requires that passed-in
77 // file names are always only constant literals.
78 if (file_name == last_file_name && line_no == last_line_no) return true;
80 int file_name_len = (int)strlen(file_name);
81 char separator = os::file_separator()[0];
82 const char* base_name = strrchr(file_name, separator);
83 if (base_name == NULL)
84 base_name = file_name;
86 // scan the SuppressErrorAt option
87 const char* cp = SuppressErrorAt;
88 for (;;) {
89 const char* sfile;
90 int sfile_len;
91 int sline;
92 bool noisy;
93 while ((*cp) != '\0' && is_token_break(*cp)) cp++;
94 if ((*cp) == '\0') break;
95 sfile = cp;
96 while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':') cp++;
97 sfile_len = cp - sfile;
98 if ((*cp) == ':') cp++;
99 sline = 0;
100 while ((*cp) != '\0' && isdigit(*cp)) {
101 sline *= 10;
102 sline += (*cp) - '0';
103 cp++;
104 }
105 // "file:line!" means the assert suppression is not silent
106 noisy = ((*cp) == '!');
107 while ((*cp) != '\0' && !is_token_break(*cp)) cp++;
108 // match the line
109 if (sline != 0) {
110 if (sline != line_no) continue;
111 }
112 // match the file
113 if (sfile_len > 0) {
114 const char* look = file_name;
115 const char* look_max = file_name + file_name_len - sfile_len;
116 const char* foundp;
117 bool match = false;
118 while (!match
119 && (foundp = strchr(look, sfile[0])) != NULL
120 && foundp <= look_max) {
121 match = true;
122 for (int i = 1; i < sfile_len; i++) {
123 if (sfile[i] != foundp[i]) {
124 match = false;
125 break;
126 }
127 }
128 look = foundp + 1;
129 }
130 if (!match) continue;
131 }
132 // got a match!
133 if (noisy) {
134 fdStream out(defaultStream::output_fd());
135 out.print_raw("[error suppressed at ");
136 out.print_raw(base_name);
137 char buf[16];
138 jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
139 out.print_raw_cr(buf);
140 } else {
141 // update 1-element cache for fast silent matches
142 last_file_name = file_name;
143 last_line_no = line_no;
144 }
145 return true;
146 }
148 if (!is_error_reported()) {
149 // print a friendly hint:
150 fdStream out(defaultStream::output_fd());
151 out.print_raw_cr("# To suppress the following error report, specify this argument");
152 out.print_raw ("# after -XX: or in .hotspotrc: SuppressErrorAt=");
153 out.print_raw (base_name);
154 char buf[16];
155 jio_snprintf(buf, sizeof(buf), ":%d", line_no);
156 out.print_raw_cr(buf);
157 }
158 return false;
159 }
161 #undef is_token_break
163 #else
165 // Place-holder for non-existent suppression check:
166 #define error_is_suppressed(file_name, line_no) (false)
168 #endif //PRODUCT
170 void report_vm_error(const char* file, int line, const char* error_msg,
171 const char* detail_msg)
172 {
173 if (Debugging || error_is_suppressed(file, line)) return;
174 Thread* const thread = ThreadLocalStorage::get_thread_slow();
175 VMError err(thread, file, line, error_msg, detail_msg);
176 err.report_and_die();
177 }
179 void report_fatal(const char* file, int line, const char* message)
180 {
181 report_vm_error(file, line, "fatal error", message);
182 }
184 // Used by report_vm_out_of_memory to detect recursion.
185 static jint _exiting_out_of_mem = 0;
187 void report_vm_out_of_memory(const char* file, int line, size_t size,
188 const char* message) {
189 if (Debugging || error_is_suppressed(file, line)) return;
191 // We try to gather additional information for the first out of memory
192 // error only; gathering additional data might cause an allocation and a
193 // recursive out_of_memory condition.
195 const jint exiting = 1;
196 // If we succeed in changing the value, we're the first one in.
197 bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting;
199 if (first_time_here) {
200 Thread* thread = ThreadLocalStorage::get_thread_slow();
201 VMError(thread, file, line, size, message).report_and_die();
202 }
204 // Dump core and abort
205 vm_abort(true);
206 }
208 void report_should_not_call(const char* file, int line) {
209 report_vm_error(file, line, "ShouldNotCall()");
210 }
212 void report_should_not_reach_here(const char* file, int line) {
213 report_vm_error(file, line, "ShouldNotReachHere()");
214 }
216 void report_unimplemented(const char* file, int line) {
217 report_vm_error(file, line, "Unimplemented()");
218 }
220 void report_untested(const char* file, int line, const char* message) {
221 #ifndef PRODUCT
222 warning("Untested: %s in %s: %d\n", message, file, line);
223 #endif // PRODUCT
224 }
226 void report_java_out_of_memory(const char* message) {
227 static jint out_of_memory_reported = 0;
229 // A number of threads may attempt to report OutOfMemoryError at around the
230 // same time. To avoid dumping the heap or executing the data collection
231 // commands multiple times we just do it once when the first threads reports
232 // the error.
233 if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
234 // create heap dump before OnOutOfMemoryError commands are executed
235 if (HeapDumpOnOutOfMemoryError) {
236 tty->print_cr("java.lang.OutOfMemoryError: %s", message);
237 HeapDumper::dump_heap();
238 }
240 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
241 VMError err(message);
242 err.report_java_out_of_memory();
243 }
244 }
245 }
248 extern "C" void ps();
250 static bool error_reported = false;
252 // call this when the VM is dying--it might loosen some asserts
253 void set_error_reported() {
254 error_reported = true;
255 }
257 bool is_error_reported() {
258 return error_reported;
259 }
261 #ifndef PRODUCT
262 #include <signal.h>
264 void test_error_handler(size_t test_num)
265 {
266 if (test_num == 0) return;
268 // If asserts are disabled, use the corresponding guarantee instead.
269 size_t n = test_num;
270 NOT_DEBUG(if (n <= 2) n += 2);
272 const char* const str = "hello";
273 const size_t num = (size_t)os::vm_page_size();
275 const char* const eol = os::line_separator();
276 const char* const msg = "this message should be truncated during formatting";
278 // Keep this in sync with test/runtime/6888954/vmerrors.sh.
279 switch (n) {
280 case 1: assert(str == NULL, "expected null");
281 case 2: assert(num == 1023 && *str == 'X',
282 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
283 case 3: guarantee(str == NULL, "expected null");
284 case 4: guarantee(num == 1023 && *str == 'X',
285 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
286 case 5: fatal("expected null");
287 case 6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
288 case 7: fatal(err_msg("%s%s# %s%s# %s%s# %s%s# %s%s# "
289 "%s%s# %s%s# %s%s# %s%s# %s%s# "
290 "%s%s# %s%s# %s%s# %s%s# %s",
291 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
292 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
293 msg, eol, msg, eol, msg, eol, msg, eol, msg));
294 case 8: vm_exit_out_of_memory(num, "ChunkPool::allocate");
295 case 9: ShouldNotCallThis();
296 case 10: ShouldNotReachHere();
297 case 11: Unimplemented();
298 // This is last because it does not generate an hs_err* file on Windows.
299 case 12: os::signal_raise(SIGSEGV);
301 default: ShouldNotReachHere();
302 }
303 }
304 #endif // #ifndef PRODUCT
306 // ------ helper functions for debugging go here ------------
308 #ifndef PRODUCT
309 // All debug entries should be wrapped with a stack allocated
310 // Command object. It makes sure a resource mark is set and
311 // flushes the logfile to prevent file sharing problems.
313 class Command : public StackObj {
314 private:
315 ResourceMark rm;
316 ResetNoHandleMark rnhm;
317 HandleMark hm;
318 bool debug_save;
319 public:
320 static int level;
321 Command(const char* str) {
322 debug_save = Debugging;
323 Debugging = true;
324 if (level++ > 0) return;
325 tty->cr();
326 tty->print_cr("\"Executing %s\"", str);
327 }
329 ~Command() { tty->flush(); Debugging = debug_save; level--; }
330 };
332 int Command::level = 0;
334 extern "C" void blob(CodeBlob* cb) {
335 Command c("blob");
336 cb->print();
337 }
340 extern "C" void dump_vtable(address p) {
341 Command c("dump_vtable");
342 klassOop k = (klassOop)p;
343 instanceKlass::cast(k)->vtable()->print();
344 }
347 extern "C" void nm(intptr_t p) {
348 // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
349 Command c("nm");
350 CodeBlob* cb = CodeCache::find_blob((address)p);
351 if (cb == NULL) {
352 tty->print_cr("NULL");
353 } else {
354 cb->print();
355 }
356 }
359 extern "C" void disnm(intptr_t p) {
360 Command c("disnm");
361 CodeBlob* cb = CodeCache::find_blob((address) p);
362 cb->print();
363 Disassembler::decode(cb);
364 }
367 extern "C" void printnm(intptr_t p) {
368 char buffer[256];
369 sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
370 Command c(buffer);
371 CodeBlob* cb = CodeCache::find_blob((address) p);
372 if (cb->is_nmethod()) {
373 nmethod* nm = (nmethod*)cb;
374 nm->print_nmethod(true);
375 }
376 }
379 extern "C" void universe() {
380 Command c("universe");
381 Universe::print();
382 }
385 extern "C" void verify() {
386 // try to run a verify on the entire system
387 // note: this may not be safe if we're not at a safepoint; for debugging,
388 // this manipulates the safepoint settings to avoid assertion failures
389 Command c("universe verify");
390 bool safe = SafepointSynchronize::is_at_safepoint();
391 if (!safe) {
392 tty->print_cr("warning: not at safepoint -- verify may fail");
393 SafepointSynchronize::set_is_at_safepoint();
394 }
395 // Ensure Eden top is correct before verification
396 Universe::heap()->prepare_for_verify();
397 Universe::verify(true);
398 if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
399 }
402 extern "C" void pp(void* p) {
403 Command c("pp");
404 FlagSetting fl(PrintVMMessages, true);
405 if (Universe::heap()->is_in(p)) {
406 oop obj = oop(p);
407 obj->print();
408 } else {
409 tty->print("%#p", p);
410 }
411 }
414 // pv: print vm-printable object
415 extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); }
416 extern "C" void findpc(intptr_t x);
418 extern "C" void ps() { // print stack
419 Command c("ps");
422 // Prints the stack of the current Java thread
423 JavaThread* p = JavaThread::active();
424 tty->print(" for thread: ");
425 p->print();
426 tty->cr();
428 if (p->has_last_Java_frame()) {
429 // If the last_Java_fp is set we are in C land and
430 // can call the standard stack_trace function.
431 p->trace_stack();
432 } else {
433 frame f = os::current_frame();
434 RegisterMap reg_map(p);
435 f = f.sender(®_map);
436 tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
437 p->trace_stack_from(vframe::new_vframe(&f, ®_map, p));
438 pd_ps(f);
439 }
441 }
444 extern "C" void psf() { // print stack frames
445 {
446 Command c("psf");
447 JavaThread* p = JavaThread::active();
448 tty->print(" for thread: ");
449 p->print();
450 tty->cr();
451 if (p->has_last_Java_frame()) {
452 p->trace_frames();
453 }
454 }
455 }
458 extern "C" void threads() {
459 Command c("threads");
460 Threads::print(false, true);
461 }
464 extern "C" void psd() {
465 Command c("psd");
466 SystemDictionary::print();
467 }
470 extern "C" void safepoints() {
471 Command c("safepoints");
472 SafepointSynchronize::print_state();
473 }
476 extern "C" void pss() { // print all stacks
477 Command c("pss");
478 Threads::print(true, true);
479 }
482 extern "C" void debug() { // to set things up for compiler debugging
483 Command c("debug");
484 WizardMode = true;
485 PrintVMMessages = PrintCompilation = true;
486 PrintInlining = PrintAssembly = true;
487 tty->flush();
488 }
491 extern "C" void ndebug() { // undo debug()
492 Command c("ndebug");
493 PrintCompilation = false;
494 PrintInlining = PrintAssembly = false;
495 tty->flush();
496 }
499 extern "C" void flush() {
500 Command c("flush");
501 tty->flush();
502 }
505 extern "C" void events() {
506 Command c("events");
507 Events::print_last(tty, 50);
508 }
511 extern "C" void nevents(int n) {
512 Command c("events");
513 Events::print_last(tty, n);
514 }
517 // Given a heap address that was valid before the most recent GC, if
518 // the oop that used to contain it is still live, prints the new
519 // location of the oop and the address. Useful for tracking down
520 // certain kinds of naked oop and oop map bugs.
521 extern "C" void pnl(intptr_t old_heap_addr) {
522 // Print New Location of old heap address
523 Command c("pnl");
524 #ifndef VALIDATE_MARK_SWEEP
525 tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled");
526 #else
527 MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr);
528 #endif
529 }
532 extern "C" methodOop findm(intptr_t pc) {
533 Command c("findm");
534 nmethod* nm = CodeCache::find_nmethod((address)pc);
535 return (nm == NULL) ? (methodOop)NULL : nm->method();
536 }
539 extern "C" nmethod* findnm(intptr_t addr) {
540 Command c("findnm");
541 return CodeCache::find_nmethod((address)addr);
542 }
544 static address same_page(address x, address y) {
545 intptr_t page_bits = -os::vm_page_size();
546 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) {
547 return x;
548 } else if (x > y) {
549 return (address)(intptr_t(y) | ~page_bits) + 1;
550 } else {
551 return (address)(intptr_t(y) & page_bits);
552 }
553 }
555 class LookForRefInGenClosure : public OopsInGenClosure {
556 public:
557 oop target;
558 void do_oop(oop* o) {
559 if (o != NULL && *o == target) {
560 tty->print_cr(INTPTR_FORMAT, o);
561 }
562 }
563 void do_oop(narrowOop* o) { ShouldNotReachHere(); }
564 };
567 class LookForRefInObjectClosure : public ObjectClosure {
568 private:
569 LookForRefInGenClosure look_in_object;
570 public:
571 LookForRefInObjectClosure(oop target) { look_in_object.target = target; }
572 void do_object(oop obj) {
573 obj->oop_iterate(&look_in_object);
574 }
575 };
578 static void findref(intptr_t x) {
579 CollectedHeap *ch = Universe::heap();
580 LookForRefInGenClosure lookFor;
581 lookFor.target = (oop) x;
582 LookForRefInObjectClosure look_in_object((oop) x);
584 tty->print_cr("Searching heap:");
585 ch->object_iterate(&look_in_object);
587 tty->print_cr("Searching strong roots:");
588 Universe::oops_do(&lookFor, false);
589 JNIHandles::oops_do(&lookFor); // Global (strong) JNI handles
590 Threads::oops_do(&lookFor, NULL);
591 ObjectSynchronizer::oops_do(&lookFor);
592 //FlatProfiler::oops_do(&lookFor);
593 SystemDictionary::oops_do(&lookFor);
595 tty->print_cr("Searching code cache:");
596 CodeCache::oops_do(&lookFor);
598 tty->print_cr("Done.");
599 }
601 class FindClassObjectClosure: public ObjectClosure {
602 private:
603 const char* _target;
604 public:
605 FindClassObjectClosure(const char name[]) { _target = name; }
607 virtual void do_object(oop obj) {
608 if (obj->is_klass()) {
609 Klass* k = klassOop(obj)->klass_part();
610 if (k->name() != NULL) {
611 ResourceMark rm;
612 const char* ext = k->external_name();
613 if ( strcmp(_target, ext) == 0 ) {
614 tty->print_cr("Found " INTPTR_FORMAT, obj);
615 obj->print();
616 }
617 }
618 }
619 }
620 };
622 //
623 extern "C" void findclass(const char name[]) {
624 Command c("findclass");
625 if (name != NULL) {
626 tty->print_cr("Finding class %s -> ", name);
627 FindClassObjectClosure srch(name);
628 Universe::heap()->permanent_object_iterate(&srch);
629 }
630 }
632 // Another interface that isn't ambiguous in dbx.
633 // Can we someday rename the other find to hsfind?
634 extern "C" void hsfind(intptr_t x) {
635 Command c("hsfind");
636 os::print_location(tty, x, false);
637 }
640 extern "C" void hsfindref(intptr_t x) {
641 Command c("hsfindref");
642 findref(x);
643 }
645 extern "C" void find(intptr_t x) {
646 Command c("find");
647 os::print_location(tty, x, false);
648 }
651 extern "C" void findpc(intptr_t x) {
652 Command c("findpc");
653 os::print_location(tty, x, true);
654 }
657 // int versions of all methods to avoid having to type type casts in the debugger
659 void pp(intptr_t p) { pp((void*)p); }
660 void pp(oop p) { pp((void*)p); }
662 void help() {
663 Command c("help");
664 tty->print_cr("basic");
665 tty->print_cr(" pp(void* p) - try to make sense of p");
666 tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
667 tty->print_cr(" ps() - print current thread stack");
668 tty->print_cr(" pss() - print all thread stacks");
669 tty->print_cr(" pm(int pc) - print methodOop given compiled PC");
670 tty->print_cr(" findm(intptr_t pc) - finds methodOop");
671 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
673 tty->print_cr("misc.");
674 tty->print_cr(" flush() - flushes the log file");
675 tty->print_cr(" events() - dump last 50 events");
678 tty->print_cr("compiler debugging");
679 tty->print_cr(" debug() - to set things up for compiler debugging");
680 tty->print_cr(" ndebug() - undo debug");
681 }
683 #if 0
685 // BobV's command parser for debugging on windows when nothing else works.
687 enum CommandID {
688 CMDID_HELP,
689 CMDID_QUIT,
690 CMDID_HSFIND,
691 CMDID_PSS,
692 CMDID_PS,
693 CMDID_PSF,
694 CMDID_FINDM,
695 CMDID_FINDNM,
696 CMDID_PP,
697 CMDID_BPT,
698 CMDID_EXIT,
699 CMDID_VERIFY,
700 CMDID_THREADS,
701 CMDID_ILLEGAL = 99
702 };
704 struct CommandParser {
705 char *name;
706 CommandID code;
707 char *description;
708 };
710 struct CommandParser CommandList[] = {
711 (char *)"help", CMDID_HELP, " Dump this list",
712 (char *)"quit", CMDID_QUIT, " Return from this routine",
713 (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address",
714 (char *)"ps", CMDID_PS, " Print Current Thread Stack Trace",
715 (char *)"pss", CMDID_PSS, " Print All Thread Stack Trace",
716 (char *)"psf", CMDID_PSF, " Print All Stack Frames",
717 (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC",
718 (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC",
719 (char *)"pp", CMDID_PP, " Find out something about a pointer",
720 (char *)"break", CMDID_BPT, " Execute a breakpoint",
721 (char *)"exitvm", CMDID_EXIT, "Exit the VM",
722 (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify",
723 (char *)"thread", CMDID_THREADS, "Dump Info on all Threads",
724 (char *)0, CMDID_ILLEGAL
725 };
728 // get_debug_command()
729 //
730 // Read a command from standard input.
731 // This is useful when you have a debugger
732 // which doesn't support calling into functions.
733 //
734 void get_debug_command()
735 {
736 ssize_t count;
737 int i,j;
738 bool gotcommand;
739 intptr_t addr;
740 char buffer[256];
741 nmethod *nm;
742 methodOop m;
744 tty->print_cr("You have entered the diagnostic command interpreter");
745 tty->print("The supported commands are:\n");
746 for ( i=0; ; i++ ) {
747 if ( CommandList[i].code == CMDID_ILLEGAL )
748 break;
749 tty->print_cr(" %s \n", CommandList[i].name );
750 }
752 while ( 1 ) {
753 gotcommand = false;
754 tty->print("Please enter a command: ");
755 count = scanf("%s", buffer) ;
756 if ( count >=0 ) {
757 for ( i=0; ; i++ ) {
758 if ( CommandList[i].code == CMDID_ILLEGAL ) {
759 if (!gotcommand) tty->print("Invalid command, please try again\n");
760 break;
761 }
762 if ( strcmp(buffer, CommandList[i].name) == 0 ) {
763 gotcommand = true;
764 switch ( CommandList[i].code ) {
765 case CMDID_PS:
766 ps();
767 break;
768 case CMDID_PSS:
769 pss();
770 break;
771 case CMDID_PSF:
772 psf();
773 break;
774 case CMDID_FINDM:
775 tty->print("Please enter the hex addr to pass to findm: ");
776 scanf("%I64X", &addr);
777 m = (methodOop)findm(addr);
778 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m);
779 break;
780 case CMDID_FINDNM:
781 tty->print("Please enter the hex addr to pass to findnm: ");
782 scanf("%I64X", &addr);
783 nm = (nmethod*)findnm(addr);
784 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm);
785 break;
786 case CMDID_PP:
787 tty->print("Please enter the hex addr to pass to pp: ");
788 scanf("%I64X", &addr);
789 pp((void*)addr);
790 break;
791 case CMDID_EXIT:
792 exit(0);
793 case CMDID_HELP:
794 tty->print("Here are the supported commands: ");
795 for ( j=0; ; j++ ) {
796 if ( CommandList[j].code == CMDID_ILLEGAL )
797 break;
798 tty->print_cr(" %s -- %s\n", CommandList[j].name,
799 CommandList[j].description );
800 }
801 break;
802 case CMDID_QUIT:
803 return;
804 break;
805 case CMDID_BPT:
806 BREAKPOINT;
807 break;
808 case CMDID_VERIFY:
809 verify();;
810 break;
811 case CMDID_THREADS:
812 threads();;
813 break;
814 case CMDID_HSFIND:
815 tty->print("Please enter the hex addr to pass to hsfind: ");
816 scanf("%I64X", &addr);
817 tty->print("Calling hsfind(0x%I64X)\n", addr);
818 hsfind(addr);
819 break;
820 default:
821 case CMDID_ILLEGAL:
822 break;
823 }
824 }
825 }
826 }
827 }
828 }
829 #endif
831 #endif // PRODUCT