Mon, 09 Mar 2009 13:28:46 -0700
6814575: Update copyright year
Summary: Update copyright for files that have been modified in 2009, up to 03/09
Reviewed-by: katleman, tbell, ohair
1 /*
2 * Copyright 1997-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any 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 assert_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 assert_is_suppressed(file_name, line_no) (false)
168 #endif //PRODUCT
170 void report_assertion_failure(const char* file_name, int line_no, const char* message) {
171 if (Debugging || assert_is_suppressed(file_name, line_no)) return;
172 VMError err(ThreadLocalStorage::get_thread_slow(), message, file_name, line_no);
173 err.report_and_die();
174 }
176 void report_fatal(const char* file_name, int line_no, const char* message) {
177 if (Debugging || assert_is_suppressed(file_name, line_no)) return;
178 VMError err(ThreadLocalStorage::get_thread_slow(), message, file_name, line_no);
179 err.report_and_die();
180 }
182 void report_fatal_vararg(const char* file_name, int line_no, const char* format, ...) {
183 char buffer[256];
184 va_list ap;
185 va_start(ap, format);
186 jio_vsnprintf(buffer, sizeof(buffer), format, ap);
187 va_end(ap);
188 report_fatal(file_name, line_no, buffer);
189 }
192 // Used by report_vm_out_of_memory to detect recursion.
193 static jint _exiting_out_of_mem = 0;
195 // Just passing the flow to VMError to handle error
196 void report_vm_out_of_memory(const char* file_name, int line_no, size_t size, const char* message) {
197 if (Debugging || assert_is_suppressed(file_name, line_no)) return;
199 // We try to gather additional information for the first out of memory
200 // error only; gathering additional data might cause an allocation and a
201 // recursive out_of_memory condition.
203 const jint exiting = 1;
204 // If we succeed in changing the value, we're the first one in.
205 bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting;
207 if (first_time_here) {
208 Thread* thread = ThreadLocalStorage::get_thread_slow();
209 VMError(thread, size, message, file_name, line_no).report_and_die();
210 }
212 // Dump core and abort
213 vm_abort(true);
214 }
216 void report_vm_out_of_memory_vararg(const char* file_name, int line_no, size_t size, const char* format, ...) {
217 char buffer[256];
218 va_list ap;
219 va_start(ap, format);
220 jio_vsnprintf(buffer, sizeof(buffer), format, ap);
221 va_end(ap);
222 report_vm_out_of_memory(file_name, line_no, size, buffer);
223 }
225 void report_should_not_call(const char* file_name, int line_no) {
226 if (Debugging || assert_is_suppressed(file_name, line_no)) return;
227 VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotCall()", file_name, line_no);
228 err.report_and_die();
229 }
232 void report_should_not_reach_here(const char* file_name, int line_no) {
233 if (Debugging || assert_is_suppressed(file_name, line_no)) return;
234 VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotReachHere()", file_name, line_no);
235 err.report_and_die();
236 }
239 void report_unimplemented(const char* file_name, int line_no) {
240 if (Debugging || assert_is_suppressed(file_name, line_no)) return;
241 VMError err(ThreadLocalStorage::get_thread_slow(), "Unimplemented()", file_name, line_no);
242 err.report_and_die();
243 }
246 void report_untested(const char* file_name, int line_no, const char* msg) {
247 #ifndef PRODUCT
248 warning("Untested: %s in %s: %d\n", msg, file_name, line_no);
249 #endif // PRODUCT
250 }
252 void report_java_out_of_memory(const char* message) {
253 static jint out_of_memory_reported = 0;
255 // A number of threads may attempt to report OutOfMemoryError at around the
256 // same time. To avoid dumping the heap or executing the data collection
257 // commands multiple times we just do it once when the first threads reports
258 // the error.
259 if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
260 // create heap dump before OnOutOfMemoryError commands are executed
261 if (HeapDumpOnOutOfMemoryError) {
262 tty->print_cr("java.lang.OutOfMemoryError: %s", message);
263 HeapDumper::dump_heap();
264 }
266 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
267 VMError err(message);
268 err.report_java_out_of_memory();
269 }
270 }
271 }
274 extern "C" void ps();
276 static bool error_reported = false;
278 // call this when the VM is dying--it might loosen some asserts
279 void set_error_reported() {
280 error_reported = true;
281 }
283 bool is_error_reported() {
284 return error_reported;
285 }
287 // ------ helper functions for debugging go here ------------
289 #ifndef PRODUCT
290 // All debug entries should be wrapped with a stack allocated
291 // Command object. It makes sure a resource mark is set and
292 // flushes the logfile to prevent file sharing problems.
294 class Command : public StackObj {
295 private:
296 ResourceMark rm;
297 ResetNoHandleMark rnhm;
298 HandleMark hm;
299 bool debug_save;
300 public:
301 static int level;
302 Command(const char* str) {
303 debug_save = Debugging;
304 Debugging = true;
305 if (level++ > 0) return;
306 tty->cr();
307 tty->print_cr("\"Executing %s\"", str);
308 }
310 ~Command() { tty->flush(); Debugging = debug_save; level--; }
311 };
313 int Command::level = 0;
315 extern "C" void blob(CodeBlob* cb) {
316 Command c("blob");
317 cb->print();
318 }
321 extern "C" void dump_vtable(address p) {
322 Command c("dump_vtable");
323 klassOop k = (klassOop)p;
324 instanceKlass::cast(k)->vtable()->print();
325 }
328 extern "C" void nm(intptr_t p) {
329 // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
330 Command c("nm");
331 CodeBlob* cb = CodeCache::find_blob((address)p);
332 if (cb == NULL) {
333 tty->print_cr("NULL");
334 } else {
335 cb->print();
336 }
337 }
340 extern "C" void disnm(intptr_t p) {
341 Command c("disnm");
342 CodeBlob* cb = CodeCache::find_blob((address) p);
343 cb->print();
344 Disassembler::decode(cb);
345 }
348 extern "C" void printnm(intptr_t p) {
349 char buffer[256];
350 sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
351 Command c(buffer);
352 CodeBlob* cb = CodeCache::find_blob((address) p);
353 if (cb->is_nmethod()) {
354 nmethod* nm = (nmethod*)cb;
355 nm->print_nmethod(true);
356 }
357 }
360 extern "C" void universe() {
361 Command c("universe");
362 Universe::print();
363 }
366 extern "C" void verify() {
367 // try to run a verify on the entire system
368 // note: this may not be safe if we're not at a safepoint; for debugging,
369 // this manipulates the safepoint settings to avoid assertion failures
370 Command c("universe verify");
371 bool safe = SafepointSynchronize::is_at_safepoint();
372 if (!safe) {
373 tty->print_cr("warning: not at safepoint -- verify may fail");
374 SafepointSynchronize::set_is_at_safepoint();
375 }
376 // Ensure Eden top is correct before verification
377 Universe::heap()->prepare_for_verify();
378 Universe::verify(true);
379 if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
380 }
383 extern "C" void pp(void* p) {
384 Command c("pp");
385 FlagSetting fl(PrintVMMessages, true);
386 if (Universe::heap()->is_in(p)) {
387 oop obj = oop(p);
388 obj->print();
389 } else {
390 tty->print("%#p", p);
391 }
392 }
395 // pv: print vm-printable object
396 extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); }
397 extern "C" void findpc(intptr_t x);
399 extern "C" void ps() { // print stack
400 Command c("ps");
403 // Prints the stack of the current Java thread
404 JavaThread* p = JavaThread::active();
405 tty->print(" for thread: ");
406 p->print();
407 tty->cr();
409 if (p->has_last_Java_frame()) {
410 // If the last_Java_fp is set we are in C land and
411 // can call the standard stack_trace function.
412 p->trace_stack();
413 } else {
414 frame f = os::current_frame();
415 RegisterMap reg_map(p);
416 f = f.sender(®_map);
417 tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
418 p->trace_stack_from(vframe::new_vframe(&f, ®_map, p));
419 pd_ps(f);
420 }
422 }
425 extern "C" void psf() { // print stack frames
426 {
427 Command c("psf");
428 JavaThread* p = JavaThread::active();
429 tty->print(" for thread: ");
430 p->print();
431 tty->cr();
432 if (p->has_last_Java_frame()) {
433 p->trace_frames();
434 }
435 }
436 }
439 extern "C" void threads() {
440 Command c("threads");
441 Threads::print(false, true);
442 }
445 extern "C" void psd() {
446 Command c("psd");
447 SystemDictionary::print();
448 }
451 extern "C" void safepoints() {
452 Command c("safepoints");
453 SafepointSynchronize::print_state();
454 }
457 extern "C" void pss() { // print all stacks
458 Command c("pss");
459 Threads::print(true, true);
460 }
463 extern "C" void debug() { // to set things up for compiler debugging
464 Command c("debug");
465 WizardMode = true;
466 PrintVMMessages = PrintCompilation = true;
467 PrintInlining = PrintAssembly = true;
468 tty->flush();
469 }
472 extern "C" void ndebug() { // undo debug()
473 Command c("ndebug");
474 PrintCompilation = false;
475 PrintInlining = PrintAssembly = false;
476 tty->flush();
477 }
480 extern "C" void flush() {
481 Command c("flush");
482 tty->flush();
483 }
486 extern "C" void events() {
487 Command c("events");
488 Events::print_last(tty, 50);
489 }
492 extern "C" void nevents(int n) {
493 Command c("events");
494 Events::print_last(tty, n);
495 }
498 // Given a heap address that was valid before the most recent GC, if
499 // the oop that used to contain it is still live, prints the new
500 // location of the oop and the address. Useful for tracking down
501 // certain kinds of naked oop and oop map bugs.
502 extern "C" void pnl(intptr_t old_heap_addr) {
503 // Print New Location of old heap address
504 Command c("pnl");
505 #ifndef VALIDATE_MARK_SWEEP
506 tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled");
507 #else
508 MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr);
509 #endif
510 }
513 extern "C" methodOop findm(intptr_t pc) {
514 Command c("findm");
515 nmethod* nm = CodeCache::find_nmethod((address)pc);
516 return (nm == NULL) ? (methodOop)NULL : nm->method();
517 }
520 extern "C" nmethod* findnm(intptr_t addr) {
521 Command c("findnm");
522 return CodeCache::find_nmethod((address)addr);
523 }
525 static address same_page(address x, address y) {
526 intptr_t page_bits = -os::vm_page_size();
527 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) {
528 return x;
529 } else if (x > y) {
530 return (address)(intptr_t(y) | ~page_bits) + 1;
531 } else {
532 return (address)(intptr_t(y) & page_bits);
533 }
534 }
537 static void find(intptr_t x, bool print_pc) {
538 address addr = (address)x;
540 CodeBlob* b = CodeCache::find_blob_unsafe(addr);
541 if (b != NULL) {
542 if (b->is_buffer_blob()) {
543 // the interpreter is generated into a buffer blob
544 InterpreterCodelet* i = Interpreter::codelet_containing(addr);
545 if (i != NULL) {
546 i->print();
547 return;
548 }
549 if (Interpreter::contains(addr)) {
550 tty->print_cr(INTPTR_FORMAT " is pointing into interpreter code (not bytecode specific)", addr);
551 return;
552 }
553 //
554 if (AdapterHandlerLibrary::contains(b)) {
555 AdapterHandlerLibrary::print_handler(b);
556 }
557 // the stubroutines are generated into a buffer blob
558 StubCodeDesc* d = StubCodeDesc::desc_for(addr);
559 if (d != NULL) {
560 d->print();
561 if (print_pc) tty->cr();
562 return;
563 }
564 if (StubRoutines::contains(addr)) {
565 tty->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) stub routine", addr);
566 return;
567 }
568 // the InlineCacheBuffer is using stubs generated into a buffer blob
569 if (InlineCacheBuffer::contains(addr)) {
570 tty->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr);
571 return;
572 }
573 VtableStub* v = VtableStubs::stub_containing(addr);
574 if (v != NULL) {
575 v->print();
576 return;
577 }
578 }
579 if (print_pc && b->is_nmethod()) {
580 ResourceMark rm;
581 tty->print("%#p: Compiled ", addr);
582 ((nmethod*)b)->method()->print_value_on(tty);
583 tty->print(" = (CodeBlob*)" INTPTR_FORMAT, b);
584 tty->cr();
585 return;
586 }
587 if ( b->is_nmethod()) {
588 if (b->is_zombie()) {
589 tty->print_cr(INTPTR_FORMAT " is zombie nmethod", b);
590 } else if (b->is_not_entrant()) {
591 tty->print_cr(INTPTR_FORMAT " is non-entrant nmethod", b);
592 }
593 }
594 b->print();
595 return;
596 }
598 if (Universe::heap()->is_in(addr)) {
599 HeapWord* p = Universe::heap()->block_start(addr);
600 bool print = false;
601 // If we couldn't find it it just may mean that heap wasn't parseable
602 // See if we were just given an oop directly
603 if (p != NULL && Universe::heap()->block_is_obj(p)) {
604 print = true;
605 } else if (p == NULL && ((oopDesc*)addr)->is_oop()) {
606 p = (HeapWord*) addr;
607 print = true;
608 }
609 if (print) {
610 oop(p)->print();
611 if (p != (HeapWord*)x && oop(p)->is_constMethod() &&
612 constMethodOop(p)->contains(addr)) {
613 Thread *thread = Thread::current();
614 HandleMark hm(thread);
615 methodHandle mh (thread, constMethodOop(p)->method());
616 if (!mh->is_native()) {
617 tty->print_cr("bci_from(%p) = %d; print_codes():",
618 addr, mh->bci_from(address(x)));
619 mh->print_codes();
620 }
621 }
622 return;
623 }
624 } else if (Universe::heap()->is_in_reserved(addr)) {
625 tty->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", addr);
626 return;
627 }
629 if (JNIHandles::is_global_handle((jobject) addr)) {
630 tty->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
631 return;
632 }
633 if (JNIHandles::is_weak_global_handle((jobject) addr)) {
634 tty->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr);
635 return;
636 }
637 if (JNIHandleBlock::any_contains((jobject) addr)) {
638 tty->print_cr(INTPTR_FORMAT " is a local jni handle", addr);
639 return;
640 }
642 for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
643 // Check for privilege stack
644 if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) {
645 tty->print_cr(INTPTR_FORMAT " is pointing into the privilege stack for thread: " INTPTR_FORMAT, addr, thread);
646 return;
647 }
648 // If the addr is a java thread print information about that.
649 if (addr == (address)thread) {
650 thread->print();
651 return;
652 }
653 }
655 // Try an OS specific find
656 if (os::find(addr)) {
657 return;
658 }
660 if (print_pc) {
661 tty->print_cr(INTPTR_FORMAT ": probably in C++ code; check debugger", addr);
662 Disassembler::decode(same_page(addr-40,addr),same_page(addr+40,addr));
663 return;
664 }
666 tty->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr);
667 }
670 class LookForRefInGenClosure : public OopsInGenClosure {
671 public:
672 oop target;
673 void do_oop(oop* o) {
674 if (o != NULL && *o == target) {
675 tty->print_cr(INTPTR_FORMAT, o);
676 }
677 }
678 void do_oop(narrowOop* o) { ShouldNotReachHere(); }
679 };
682 class LookForRefInObjectClosure : public ObjectClosure {
683 private:
684 LookForRefInGenClosure look_in_object;
685 public:
686 LookForRefInObjectClosure(oop target) { look_in_object.target = target; }
687 void do_object(oop obj) {
688 obj->oop_iterate(&look_in_object);
689 }
690 };
693 static void findref(intptr_t x) {
694 CollectedHeap *ch = Universe::heap();
695 LookForRefInGenClosure lookFor;
696 lookFor.target = (oop) x;
697 LookForRefInObjectClosure look_in_object((oop) x);
699 tty->print_cr("Searching heap:");
700 ch->object_iterate(&look_in_object);
702 tty->print_cr("Searching strong roots:");
703 Universe::oops_do(&lookFor, false);
704 JNIHandles::oops_do(&lookFor); // Global (strong) JNI handles
705 Threads::oops_do(&lookFor);
706 ObjectSynchronizer::oops_do(&lookFor);
707 //FlatProfiler::oops_do(&lookFor);
708 SystemDictionary::oops_do(&lookFor);
710 tty->print_cr("Done.");
711 }
713 class FindClassObjectClosure: public ObjectClosure {
714 private:
715 const char* _target;
716 public:
717 FindClassObjectClosure(const char name[]) { _target = name; }
719 virtual void do_object(oop obj) {
720 if (obj->is_klass()) {
721 Klass* k = klassOop(obj)->klass_part();
722 if (k->name() != NULL) {
723 ResourceMark rm;
724 const char* ext = k->external_name();
725 if ( strcmp(_target, ext) == 0 ) {
726 tty->print_cr("Found " INTPTR_FORMAT, obj);
727 obj->print();
728 }
729 }
730 }
731 }
732 };
734 //
735 extern "C" void findclass(const char name[]) {
736 Command c("findclass");
737 if (name != NULL) {
738 tty->print_cr("Finding class %s -> ", name);
739 FindClassObjectClosure srch(name);
740 Universe::heap()->permanent_object_iterate(&srch);
741 }
742 }
744 // Another interface that isn't ambiguous in dbx.
745 // Can we someday rename the other find to hsfind?
746 extern "C" void hsfind(intptr_t x) {
747 Command c("hsfind");
748 find(x, false);
749 }
752 extern "C" void hsfindref(intptr_t x) {
753 Command c("hsfindref");
754 findref(x);
755 }
757 extern "C" void find(intptr_t x) {
758 Command c("find");
759 find(x, false);
760 }
763 extern "C" void findpc(intptr_t x) {
764 Command c("findpc");
765 find(x, true);
766 }
769 // int versions of all methods to avoid having to type type casts in the debugger
771 void pp(intptr_t p) { pp((void*)p); }
772 void pp(oop p) { pp((void*)p); }
774 void help() {
775 Command c("help");
776 tty->print_cr("basic");
777 tty->print_cr(" pp(void* p) - try to make sense of p");
778 tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
779 tty->print_cr(" ps() - print current thread stack");
780 tty->print_cr(" pss() - print all thread stacks");
781 tty->print_cr(" pm(int pc) - print methodOop given compiled PC");
782 tty->print_cr(" findm(intptr_t pc) - finds methodOop");
783 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
785 tty->print_cr("misc.");
786 tty->print_cr(" flush() - flushes the log file");
787 tty->print_cr(" events() - dump last 50 events");
790 tty->print_cr("compiler debugging");
791 tty->print_cr(" debug() - to set things up for compiler debugging");
792 tty->print_cr(" ndebug() - undo debug");
793 }
795 #if 0
797 // BobV's command parser for debugging on windows when nothing else works.
799 enum CommandID {
800 CMDID_HELP,
801 CMDID_QUIT,
802 CMDID_HSFIND,
803 CMDID_PSS,
804 CMDID_PS,
805 CMDID_PSF,
806 CMDID_FINDM,
807 CMDID_FINDNM,
808 CMDID_PP,
809 CMDID_BPT,
810 CMDID_EXIT,
811 CMDID_VERIFY,
812 CMDID_THREADS,
813 CMDID_ILLEGAL = 99
814 };
816 struct CommandParser {
817 char *name;
818 CommandID code;
819 char *description;
820 };
822 struct CommandParser CommandList[] = {
823 (char *)"help", CMDID_HELP, " Dump this list",
824 (char *)"quit", CMDID_QUIT, " Return from this routine",
825 (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address",
826 (char *)"ps", CMDID_PS, " Print Current Thread Stack Trace",
827 (char *)"pss", CMDID_PSS, " Print All Thread Stack Trace",
828 (char *)"psf", CMDID_PSF, " Print All Stack Frames",
829 (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC",
830 (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC",
831 (char *)"pp", CMDID_PP, " Find out something about a pointer",
832 (char *)"break", CMDID_BPT, " Execute a breakpoint",
833 (char *)"exitvm", CMDID_EXIT, "Exit the VM",
834 (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify",
835 (char *)"thread", CMDID_THREADS, "Dump Info on all Threads",
836 (char *)0, CMDID_ILLEGAL
837 };
840 // get_debug_command()
841 //
842 // Read a command from standard input.
843 // This is useful when you have a debugger
844 // which doesn't support calling into functions.
845 //
846 void get_debug_command()
847 {
848 ssize_t count;
849 int i,j;
850 bool gotcommand;
851 intptr_t addr;
852 char buffer[256];
853 nmethod *nm;
854 methodOop m;
856 tty->print_cr("You have entered the diagnostic command interpreter");
857 tty->print("The supported commands are:\n");
858 for ( i=0; ; i++ ) {
859 if ( CommandList[i].code == CMDID_ILLEGAL )
860 break;
861 tty->print_cr(" %s \n", CommandList[i].name );
862 }
864 while ( 1 ) {
865 gotcommand = false;
866 tty->print("Please enter a command: ");
867 count = scanf("%s", buffer) ;
868 if ( count >=0 ) {
869 for ( i=0; ; i++ ) {
870 if ( CommandList[i].code == CMDID_ILLEGAL ) {
871 if (!gotcommand) tty->print("Invalid command, please try again\n");
872 break;
873 }
874 if ( strcmp(buffer, CommandList[i].name) == 0 ) {
875 gotcommand = true;
876 switch ( CommandList[i].code ) {
877 case CMDID_PS:
878 ps();
879 break;
880 case CMDID_PSS:
881 pss();
882 break;
883 case CMDID_PSF:
884 psf();
885 break;
886 case CMDID_FINDM:
887 tty->print("Please enter the hex addr to pass to findm: ");
888 scanf("%I64X", &addr);
889 m = (methodOop)findm(addr);
890 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m);
891 break;
892 case CMDID_FINDNM:
893 tty->print("Please enter the hex addr to pass to findnm: ");
894 scanf("%I64X", &addr);
895 nm = (nmethod*)findnm(addr);
896 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm);
897 break;
898 case CMDID_PP:
899 tty->print("Please enter the hex addr to pass to pp: ");
900 scanf("%I64X", &addr);
901 pp((void*)addr);
902 break;
903 case CMDID_EXIT:
904 exit(0);
905 case CMDID_HELP:
906 tty->print("Here are the supported commands: ");
907 for ( j=0; ; j++ ) {
908 if ( CommandList[j].code == CMDID_ILLEGAL )
909 break;
910 tty->print_cr(" %s -- %s\n", CommandList[j].name,
911 CommandList[j].description );
912 }
913 break;
914 case CMDID_QUIT:
915 return;
916 break;
917 case CMDID_BPT:
918 BREAKPOINT;
919 break;
920 case CMDID_VERIFY:
921 verify();;
922 break;
923 case CMDID_THREADS:
924 threads();;
925 break;
926 case CMDID_HSFIND:
927 tty->print("Please enter the hex addr to pass to hsfind: ");
928 scanf("%I64X", &addr);
929 tty->print("Calling hsfind(0x%I64X)\n", addr);
930 hsfind(addr);
931 break;
932 default:
933 case CMDID_ILLEGAL:
934 break;
935 }
936 }
937 }
938 }
939 }
940 }
941 #endif
943 #endif // PRODUCT