Thu, 13 Oct 2011 09:35:42 -0700
7098194: integrate macosx-port changes
Summary: Integrate bsd-port/hotspot and macosx-port/hotspot changes as of 2011.09.29.
Reviewed-by: kvn, dholmes, never, phh
Contributed-by: Christos Zoulas <christos@zoulas.com>, Greg Lewis <glewis@eyesbeyond.com>, Kurt Miller <kurt@intricatesoftware.com>, Alexander Strange <astrange@apple.com>, Mike Swingler <swingler@apple.com>, Roger Hoover <rhoover@apple.com>, Victor Hernandez <vhernandez@apple.com>, Pratik Solanki <psolanki@apple.com>
1 /*
2 * Copyright (c) 1997, 2011, 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 "precompiled.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "code/codeCache.hpp"
28 #include "code/icBuffer.hpp"
29 #include "code/nmethod.hpp"
30 #include "code/vtableStubs.hpp"
31 #include "compiler/compileBroker.hpp"
32 #include "compiler/disassembler.hpp"
33 #include "gc_implementation/shared/markSweep.hpp"
34 #include "gc_interface/collectedHeap.hpp"
35 #include "interpreter/bytecodeHistogram.hpp"
36 #include "interpreter/interpreter.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "oops/oop.inline.hpp"
40 #include "prims/privilegedStack.hpp"
41 #include "runtime/arguments.hpp"
42 #include "runtime/frame.hpp"
43 #include "runtime/java.hpp"
44 #include "runtime/sharedRuntime.hpp"
45 #include "runtime/stubCodeGenerator.hpp"
46 #include "runtime/stubRoutines.hpp"
47 #include "runtime/vframe.hpp"
48 #include "services/heapDumper.hpp"
49 #include "utilities/defaultStream.hpp"
50 #include "utilities/events.hpp"
51 #include "utilities/top.hpp"
52 #include "utilities/vmError.hpp"
53 #ifdef TARGET_OS_FAMILY_linux
54 # include "os_linux.inline.hpp"
55 # include "thread_linux.inline.hpp"
56 #endif
57 #ifdef TARGET_OS_FAMILY_solaris
58 # include "os_solaris.inline.hpp"
59 # include "thread_solaris.inline.hpp"
60 #endif
61 #ifdef TARGET_OS_FAMILY_windows
62 # include "os_windows.inline.hpp"
63 # include "thread_windows.inline.hpp"
64 #endif
65 #ifdef TARGET_OS_FAMILY_bsd
66 # include "os_bsd.inline.hpp"
67 # include "thread_bsd.inline.hpp"
68 #endif
70 #ifndef ASSERT
71 # ifdef _DEBUG
72 // NOTE: don't turn the lines below into a comment -- if you're getting
73 // a compile error here, change the settings to define ASSERT
74 ASSERT should be defined when _DEBUG is defined. It is not intended to be used for debugging
75 functions that do not slow down the system too much and thus can be left in optimized code.
76 On the other hand, the code should not be included in a production version.
77 # endif // _DEBUG
78 #endif // ASSERT
81 #ifdef _DEBUG
82 # ifndef ASSERT
83 configuration error: ASSERT must be defined in debug version
84 # endif // ASSERT
85 #endif // _DEBUG
88 #ifdef PRODUCT
89 # if -defined _DEBUG || -defined ASSERT
90 configuration error: ASSERT et al. must not be defined in PRODUCT version
91 # endif
92 #endif // PRODUCT
95 void warning(const char* format, ...) {
96 if (PrintWarnings) {
97 // In case error happens before init or during shutdown
98 if (tty == NULL) ostream_init();
100 tty->print("%s warning: ", VM_Version::vm_name());
101 va_list ap;
102 va_start(ap, format);
103 tty->vprint_cr(format, ap);
104 va_end(ap);
105 }
106 if (BreakAtWarning) BREAKPOINT;
107 }
109 #ifndef PRODUCT
111 #define is_token_break(ch) (isspace(ch) || (ch) == ',')
113 static const char* last_file_name = NULL;
114 static int last_line_no = -1;
116 // assert/guarantee/... may happen very early during VM initialization.
117 // Don't rely on anything that is initialized by Threads::create_vm(). For
118 // example, don't use tty.
119 bool error_is_suppressed(const char* file_name, int line_no) {
120 // The following 1-element cache requires that passed-in
121 // file names are always only constant literals.
122 if (file_name == last_file_name && line_no == last_line_no) return true;
124 int file_name_len = (int)strlen(file_name);
125 char separator = os::file_separator()[0];
126 const char* base_name = strrchr(file_name, separator);
127 if (base_name == NULL)
128 base_name = file_name;
130 // scan the SuppressErrorAt option
131 const char* cp = SuppressErrorAt;
132 for (;;) {
133 const char* sfile;
134 int sfile_len;
135 int sline;
136 bool noisy;
137 while ((*cp) != '\0' && is_token_break(*cp)) cp++;
138 if ((*cp) == '\0') break;
139 sfile = cp;
140 while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':') cp++;
141 sfile_len = cp - sfile;
142 if ((*cp) == ':') cp++;
143 sline = 0;
144 while ((*cp) != '\0' && isdigit(*cp)) {
145 sline *= 10;
146 sline += (*cp) - '0';
147 cp++;
148 }
149 // "file:line!" means the assert suppression is not silent
150 noisy = ((*cp) == '!');
151 while ((*cp) != '\0' && !is_token_break(*cp)) cp++;
152 // match the line
153 if (sline != 0) {
154 if (sline != line_no) continue;
155 }
156 // match the file
157 if (sfile_len > 0) {
158 const char* look = file_name;
159 const char* look_max = file_name + file_name_len - sfile_len;
160 const char* foundp;
161 bool match = false;
162 while (!match
163 && (foundp = strchr(look, sfile[0])) != NULL
164 && foundp <= look_max) {
165 match = true;
166 for (int i = 1; i < sfile_len; i++) {
167 if (sfile[i] != foundp[i]) {
168 match = false;
169 break;
170 }
171 }
172 look = foundp + 1;
173 }
174 if (!match) continue;
175 }
176 // got a match!
177 if (noisy) {
178 fdStream out(defaultStream::output_fd());
179 out.print_raw("[error suppressed at ");
180 out.print_raw(base_name);
181 char buf[16];
182 jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
183 out.print_raw_cr(buf);
184 } else {
185 // update 1-element cache for fast silent matches
186 last_file_name = file_name;
187 last_line_no = line_no;
188 }
189 return true;
190 }
192 if (!is_error_reported()) {
193 // print a friendly hint:
194 fdStream out(defaultStream::output_fd());
195 out.print_raw_cr("# To suppress the following error report, specify this argument");
196 out.print_raw ("# after -XX: or in .hotspotrc: SuppressErrorAt=");
197 out.print_raw (base_name);
198 char buf[16];
199 jio_snprintf(buf, sizeof(buf), ":%d", line_no);
200 out.print_raw_cr(buf);
201 }
202 return false;
203 }
205 #undef is_token_break
207 #else
209 // Place-holder for non-existent suppression check:
210 #define error_is_suppressed(file_name, line_no) (false)
212 #endif // !PRODUCT
214 void report_vm_error(const char* file, int line, const char* error_msg,
215 const char* detail_msg)
216 {
217 if (Debugging || error_is_suppressed(file, line)) return;
218 Thread* const thread = ThreadLocalStorage::get_thread_slow();
219 VMError err(thread, file, line, error_msg, detail_msg);
220 err.report_and_die();
221 }
223 void report_fatal(const char* file, int line, const char* message)
224 {
225 report_vm_error(file, line, "fatal error", message);
226 }
228 // Used by report_vm_out_of_memory to detect recursion.
229 static jint _exiting_out_of_mem = 0;
231 void report_vm_out_of_memory(const char* file, int line, size_t size,
232 const char* message) {
233 if (Debugging) return;
235 // We try to gather additional information for the first out of memory
236 // error only; gathering additional data might cause an allocation and a
237 // recursive out_of_memory condition.
239 const jint exiting = 1;
240 // If we succeed in changing the value, we're the first one in.
241 bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting;
243 if (first_time_here) {
244 Thread* thread = ThreadLocalStorage::get_thread_slow();
245 VMError(thread, file, line, size, message).report_and_die();
246 }
248 // Dump core and abort
249 vm_abort(true);
250 }
252 void report_should_not_call(const char* file, int line) {
253 report_vm_error(file, line, "ShouldNotCall()");
254 }
256 void report_should_not_reach_here(const char* file, int line) {
257 report_vm_error(file, line, "ShouldNotReachHere()");
258 }
260 void report_unimplemented(const char* file, int line) {
261 report_vm_error(file, line, "Unimplemented()");
262 }
264 void report_untested(const char* file, int line, const char* message) {
265 #ifndef PRODUCT
266 warning("Untested: %s in %s: %d\n", message, file, line);
267 #endif // !PRODUCT
268 }
270 void report_out_of_shared_space(SharedSpaceType shared_space) {
271 static const char* name[] = {
272 "permanent generation",
273 "shared read only space",
274 "shared read write space",
275 "shared miscellaneous data space"
276 };
277 static const char* flag[] = {
278 "PermGen",
279 "SharedReadOnlySize",
280 "SharedReadWriteSize",
281 "SharedMiscDataSize"
282 };
284 warning("\nThe %s is not large enough\n"
285 "to preload requested classes. Use -XX:%s=\n"
286 "to increase the initial size of %s.\n",
287 name[shared_space], flag[shared_space], name[shared_space]);
288 exit(2);
289 }
291 void report_java_out_of_memory(const char* message) {
292 static jint out_of_memory_reported = 0;
294 // A number of threads may attempt to report OutOfMemoryError at around the
295 // same time. To avoid dumping the heap or executing the data collection
296 // commands multiple times we just do it once when the first threads reports
297 // the error.
298 if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
299 // create heap dump before OnOutOfMemoryError commands are executed
300 if (HeapDumpOnOutOfMemoryError) {
301 tty->print_cr("java.lang.OutOfMemoryError: %s", message);
302 HeapDumper::dump_heap_from_oome();
303 }
305 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
306 VMError err(message);
307 err.report_java_out_of_memory();
308 }
309 }
310 }
312 static bool error_reported = false;
314 // call this when the VM is dying--it might loosen some asserts
315 void set_error_reported() {
316 error_reported = true;
317 }
319 bool is_error_reported() {
320 return error_reported;
321 }
323 #ifndef PRODUCT
324 #include <signal.h>
326 void test_error_handler(size_t test_num)
327 {
328 if (test_num == 0) return;
330 // If asserts are disabled, use the corresponding guarantee instead.
331 size_t n = test_num;
332 NOT_DEBUG(if (n <= 2) n += 2);
334 const char* const str = "hello";
335 const size_t num = (size_t)os::vm_page_size();
337 const char* const eol = os::line_separator();
338 const char* const msg = "this message should be truncated during formatting";
340 // Keep this in sync with test/runtime/6888954/vmerrors.sh.
341 switch (n) {
342 case 1: assert(str == NULL, "expected null");
343 case 2: assert(num == 1023 && *str == 'X',
344 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
345 case 3: guarantee(str == NULL, "expected null");
346 case 4: guarantee(num == 1023 && *str == 'X',
347 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
348 case 5: fatal("expected null");
349 case 6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
350 case 7: fatal(err_msg("%s%s# %s%s# %s%s# %s%s# %s%s# "
351 "%s%s# %s%s# %s%s# %s%s# %s%s# "
352 "%s%s# %s%s# %s%s# %s%s# %s",
353 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
354 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
355 msg, eol, msg, eol, msg, eol, msg, eol, msg));
356 case 8: vm_exit_out_of_memory(num, "ChunkPool::allocate");
357 case 9: ShouldNotCallThis();
358 case 10: ShouldNotReachHere();
359 case 11: Unimplemented();
360 // This is last because it does not generate an hs_err* file on Windows.
361 case 12: os::signal_raise(SIGSEGV);
363 default: ShouldNotReachHere();
364 }
365 }
366 #endif // !PRODUCT
368 // ------ helper functions for debugging go here ------------
370 // All debug entries should be wrapped with a stack allocated
371 // Command object. It makes sure a resource mark is set and
372 // flushes the logfile to prevent file sharing problems.
374 class Command : public StackObj {
375 private:
376 ResourceMark rm;
377 ResetNoHandleMark rnhm;
378 HandleMark hm;
379 bool debug_save;
380 public:
381 static int level;
382 Command(const char* str) {
383 debug_save = Debugging;
384 Debugging = true;
385 if (level++ > 0) return;
386 tty->cr();
387 tty->print_cr("\"Executing %s\"", str);
388 }
390 ~Command() {
391 tty->flush();
392 Debugging = debug_save;
393 level--;
394 }
395 };
397 int Command::level = 0;
399 #ifndef PRODUCT
401 extern "C" void blob(CodeBlob* cb) {
402 Command c("blob");
403 cb->print();
404 }
407 extern "C" void dump_vtable(address p) {
408 Command c("dump_vtable");
409 klassOop k = (klassOop)p;
410 instanceKlass::cast(k)->vtable()->print();
411 }
414 extern "C" void nm(intptr_t p) {
415 // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
416 Command c("nm");
417 CodeBlob* cb = CodeCache::find_blob((address)p);
418 if (cb == NULL) {
419 tty->print_cr("NULL");
420 } else {
421 cb->print();
422 }
423 }
426 extern "C" void disnm(intptr_t p) {
427 Command c("disnm");
428 CodeBlob* cb = CodeCache::find_blob((address) p);
429 nmethod* nm = cb->as_nmethod_or_null();
430 if (nm) {
431 nm->print();
432 Disassembler::decode(nm);
433 } else {
434 cb->print();
435 Disassembler::decode(cb);
436 }
437 }
440 extern "C" void printnm(intptr_t p) {
441 char buffer[256];
442 sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
443 Command c(buffer);
444 CodeBlob* cb = CodeCache::find_blob((address) p);
445 if (cb->is_nmethod()) {
446 nmethod* nm = (nmethod*)cb;
447 nm->print_nmethod(true);
448 }
449 }
452 extern "C" void universe() {
453 Command c("universe");
454 Universe::print();
455 }
458 extern "C" void verify() {
459 // try to run a verify on the entire system
460 // note: this may not be safe if we're not at a safepoint; for debugging,
461 // this manipulates the safepoint settings to avoid assertion failures
462 Command c("universe verify");
463 bool safe = SafepointSynchronize::is_at_safepoint();
464 if (!safe) {
465 tty->print_cr("warning: not at safepoint -- verify may fail");
466 SafepointSynchronize::set_is_at_safepoint();
467 }
468 // Ensure Eden top is correct before verification
469 Universe::heap()->prepare_for_verify();
470 Universe::verify(true);
471 if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
472 }
475 extern "C" void pp(void* p) {
476 Command c("pp");
477 FlagSetting fl(PrintVMMessages, true);
478 FlagSetting f2(DisplayVMOutput, true);
479 if (Universe::heap()->is_in(p)) {
480 oop obj = oop(p);
481 obj->print();
482 } else {
483 tty->print(PTR_FORMAT, p);
484 }
485 }
488 // pv: print vm-printable object
489 extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); }
490 extern "C" void findpc(intptr_t x);
492 #endif // !PRODUCT
494 extern "C" void ps() { // print stack
495 if (Thread::current() == NULL) return;
496 Command c("ps");
499 // Prints the stack of the current Java thread
500 JavaThread* p = JavaThread::active();
501 tty->print(" for thread: ");
502 p->print();
503 tty->cr();
505 if (p->has_last_Java_frame()) {
506 // If the last_Java_fp is set we are in C land and
507 // can call the standard stack_trace function.
508 #ifdef PRODUCT
509 p->print_stack();
510 } else {
511 tty->print_cr("Cannot find the last Java frame, printing stack disabled.");
512 #else // !PRODUCT
513 p->trace_stack();
514 } else {
515 frame f = os::current_frame();
516 RegisterMap reg_map(p);
517 f = f.sender(®_map);
518 tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
519 p->trace_stack_from(vframe::new_vframe(&f, ®_map, p));
520 pd_ps(f);
521 #endif // PRODUCT
522 }
524 }
526 extern "C" void pfl() {
527 // print frame layout
528 Command c("pfl");
529 JavaThread* p = JavaThread::active();
530 tty->print(" for thread: ");
531 p->print();
532 tty->cr();
533 if (p->has_last_Java_frame()) {
534 p->print_frame_layout();
535 }
536 }
538 #ifndef PRODUCT
540 extern "C" void psf() { // print stack frames
541 {
542 Command c("psf");
543 JavaThread* p = JavaThread::active();
544 tty->print(" for thread: ");
545 p->print();
546 tty->cr();
547 if (p->has_last_Java_frame()) {
548 p->trace_frames();
549 }
550 }
551 }
554 extern "C" void threads() {
555 Command c("threads");
556 Threads::print(false, true);
557 }
560 extern "C" void psd() {
561 Command c("psd");
562 SystemDictionary::print();
563 }
566 extern "C" void safepoints() {
567 Command c("safepoints");
568 SafepointSynchronize::print_state();
569 }
571 #endif // !PRODUCT
573 extern "C" void pss() { // print all stacks
574 if (Thread::current() == NULL) return;
575 Command c("pss");
576 Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
577 }
579 #ifndef PRODUCT
581 extern "C" void debug() { // to set things up for compiler debugging
582 Command c("debug");
583 WizardMode = true;
584 PrintVMMessages = PrintCompilation = true;
585 PrintInlining = PrintAssembly = true;
586 tty->flush();
587 }
590 extern "C" void ndebug() { // undo debug()
591 Command c("ndebug");
592 PrintCompilation = false;
593 PrintInlining = PrintAssembly = false;
594 tty->flush();
595 }
598 extern "C" void flush() {
599 Command c("flush");
600 tty->flush();
601 }
604 extern "C" void events() {
605 Command c("events");
606 Events::print_last(tty, 50);
607 }
610 extern "C" void nevents(int n) {
611 Command c("events");
612 Events::print_last(tty, n);
613 }
616 // Given a heap address that was valid before the most recent GC, if
617 // the oop that used to contain it is still live, prints the new
618 // location of the oop and the address. Useful for tracking down
619 // certain kinds of naked oop and oop map bugs.
620 extern "C" void pnl(intptr_t old_heap_addr) {
621 // Print New Location of old heap address
622 Command c("pnl");
623 #ifndef VALIDATE_MARK_SWEEP
624 tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled");
625 #else
626 MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr);
627 #endif
628 }
631 extern "C" methodOop findm(intptr_t pc) {
632 Command c("findm");
633 nmethod* nm = CodeCache::find_nmethod((address)pc);
634 return (nm == NULL) ? (methodOop)NULL : nm->method();
635 }
638 extern "C" nmethod* findnm(intptr_t addr) {
639 Command c("findnm");
640 return CodeCache::find_nmethod((address)addr);
641 }
643 static address same_page(address x, address y) {
644 intptr_t page_bits = -os::vm_page_size();
645 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) {
646 return x;
647 } else if (x > y) {
648 return (address)(intptr_t(y) | ~page_bits) + 1;
649 } else {
650 return (address)(intptr_t(y) & page_bits);
651 }
652 }
654 class LookForRefInGenClosure : public OopsInGenClosure {
655 public:
656 oop target;
657 void do_oop(oop* o) {
658 if (o != NULL && *o == target) {
659 tty->print_cr(INTPTR_FORMAT, o);
660 }
661 }
662 void do_oop(narrowOop* o) { ShouldNotReachHere(); }
663 };
666 class LookForRefInObjectClosure : public ObjectClosure {
667 private:
668 LookForRefInGenClosure look_in_object;
669 public:
670 LookForRefInObjectClosure(oop target) { look_in_object.target = target; }
671 void do_object(oop obj) {
672 obj->oop_iterate(&look_in_object);
673 }
674 };
677 static void findref(intptr_t x) {
678 CollectedHeap *ch = Universe::heap();
679 LookForRefInGenClosure lookFor;
680 lookFor.target = (oop) x;
681 LookForRefInObjectClosure look_in_object((oop) x);
683 tty->print_cr("Searching heap:");
684 ch->object_iterate(&look_in_object);
686 tty->print_cr("Searching strong roots:");
687 Universe::oops_do(&lookFor, false);
688 JNIHandles::oops_do(&lookFor); // Global (strong) JNI handles
689 Threads::oops_do(&lookFor, NULL);
690 ObjectSynchronizer::oops_do(&lookFor);
691 //FlatProfiler::oops_do(&lookFor);
692 SystemDictionary::oops_do(&lookFor);
694 tty->print_cr("Searching code cache:");
695 CodeCache::oops_do(&lookFor);
697 tty->print_cr("Done.");
698 }
700 class FindClassObjectClosure: public ObjectClosure {
701 private:
702 const char* _target;
703 public:
704 FindClassObjectClosure(const char name[]) { _target = name; }
706 virtual void do_object(oop obj) {
707 if (obj->is_klass()) {
708 Klass* k = klassOop(obj)->klass_part();
709 if (k->name() != NULL) {
710 ResourceMark rm;
711 const char* ext = k->external_name();
712 if ( strcmp(_target, ext) == 0 ) {
713 tty->print_cr("Found " INTPTR_FORMAT, obj);
714 obj->print();
715 }
716 }
717 }
718 }
719 };
721 //
722 extern "C" void findclass(const char name[]) {
723 Command c("findclass");
724 if (name != NULL) {
725 tty->print_cr("Finding class %s -> ", name);
726 FindClassObjectClosure srch(name);
727 Universe::heap()->permanent_object_iterate(&srch);
728 }
729 }
731 // Another interface that isn't ambiguous in dbx.
732 // Can we someday rename the other find to hsfind?
733 extern "C" void hsfind(intptr_t x) {
734 Command c("hsfind");
735 os::print_location(tty, x, false);
736 }
739 extern "C" void hsfindref(intptr_t x) {
740 Command c("hsfindref");
741 findref(x);
742 }
744 extern "C" void find(intptr_t x) {
745 Command c("find");
746 os::print_location(tty, x, false);
747 }
750 extern "C" void findpc(intptr_t x) {
751 Command c("findpc");
752 os::print_location(tty, x, true);
753 }
756 // int versions of all methods to avoid having to type type casts in the debugger
758 void pp(intptr_t p) { pp((void*)p); }
759 void pp(oop p) { pp((void*)p); }
761 void help() {
762 Command c("help");
763 tty->print_cr("basic");
764 tty->print_cr(" pp(void* p) - try to make sense of p");
765 tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
766 tty->print_cr(" ps() - print current thread stack");
767 tty->print_cr(" pss() - print all thread stacks");
768 tty->print_cr(" pm(int pc) - print methodOop given compiled PC");
769 tty->print_cr(" findm(intptr_t pc) - finds methodOop");
770 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
772 tty->print_cr("misc.");
773 tty->print_cr(" flush() - flushes the log file");
774 tty->print_cr(" events() - dump last 50 events");
777 tty->print_cr("compiler debugging");
778 tty->print_cr(" debug() - to set things up for compiler debugging");
779 tty->print_cr(" ndebug() - undo debug");
780 }
782 #if 0
784 // BobV's command parser for debugging on windows when nothing else works.
786 enum CommandID {
787 CMDID_HELP,
788 CMDID_QUIT,
789 CMDID_HSFIND,
790 CMDID_PSS,
791 CMDID_PS,
792 CMDID_PSF,
793 CMDID_FINDM,
794 CMDID_FINDNM,
795 CMDID_PP,
796 CMDID_BPT,
797 CMDID_EXIT,
798 CMDID_VERIFY,
799 CMDID_THREADS,
800 CMDID_ILLEGAL = 99
801 };
803 struct CommandParser {
804 char *name;
805 CommandID code;
806 char *description;
807 };
809 struct CommandParser CommandList[] = {
810 (char *)"help", CMDID_HELP, " Dump this list",
811 (char *)"quit", CMDID_QUIT, " Return from this routine",
812 (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address",
813 (char *)"ps", CMDID_PS, " Print Current Thread Stack Trace",
814 (char *)"pss", CMDID_PSS, " Print All Thread Stack Trace",
815 (char *)"psf", CMDID_PSF, " Print All Stack Frames",
816 (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC",
817 (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC",
818 (char *)"pp", CMDID_PP, " Find out something about a pointer",
819 (char *)"break", CMDID_BPT, " Execute a breakpoint",
820 (char *)"exitvm", CMDID_EXIT, "Exit the VM",
821 (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify",
822 (char *)"thread", CMDID_THREADS, "Dump Info on all Threads",
823 (char *)0, CMDID_ILLEGAL
824 };
827 // get_debug_command()
828 //
829 // Read a command from standard input.
830 // This is useful when you have a debugger
831 // which doesn't support calling into functions.
832 //
833 void get_debug_command()
834 {
835 ssize_t count;
836 int i,j;
837 bool gotcommand;
838 intptr_t addr;
839 char buffer[256];
840 nmethod *nm;
841 methodOop m;
843 tty->print_cr("You have entered the diagnostic command interpreter");
844 tty->print("The supported commands are:\n");
845 for ( i=0; ; i++ ) {
846 if ( CommandList[i].code == CMDID_ILLEGAL )
847 break;
848 tty->print_cr(" %s \n", CommandList[i].name );
849 }
851 while ( 1 ) {
852 gotcommand = false;
853 tty->print("Please enter a command: ");
854 count = scanf("%s", buffer) ;
855 if ( count >=0 ) {
856 for ( i=0; ; i++ ) {
857 if ( CommandList[i].code == CMDID_ILLEGAL ) {
858 if (!gotcommand) tty->print("Invalid command, please try again\n");
859 break;
860 }
861 if ( strcmp(buffer, CommandList[i].name) == 0 ) {
862 gotcommand = true;
863 switch ( CommandList[i].code ) {
864 case CMDID_PS:
865 ps();
866 break;
867 case CMDID_PSS:
868 pss();
869 break;
870 case CMDID_PSF:
871 psf();
872 break;
873 case CMDID_FINDM:
874 tty->print("Please enter the hex addr to pass to findm: ");
875 scanf("%I64X", &addr);
876 m = (methodOop)findm(addr);
877 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m);
878 break;
879 case CMDID_FINDNM:
880 tty->print("Please enter the hex addr to pass to findnm: ");
881 scanf("%I64X", &addr);
882 nm = (nmethod*)findnm(addr);
883 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm);
884 break;
885 case CMDID_PP:
886 tty->print("Please enter the hex addr to pass to pp: ");
887 scanf("%I64X", &addr);
888 pp((void*)addr);
889 break;
890 case CMDID_EXIT:
891 exit(0);
892 case CMDID_HELP:
893 tty->print("Here are the supported commands: ");
894 for ( j=0; ; j++ ) {
895 if ( CommandList[j].code == CMDID_ILLEGAL )
896 break;
897 tty->print_cr(" %s -- %s\n", CommandList[j].name,
898 CommandList[j].description );
899 }
900 break;
901 case CMDID_QUIT:
902 return;
903 break;
904 case CMDID_BPT:
905 BREAKPOINT;
906 break;
907 case CMDID_VERIFY:
908 verify();;
909 break;
910 case CMDID_THREADS:
911 threads();;
912 break;
913 case CMDID_HSFIND:
914 tty->print("Please enter the hex addr to pass to hsfind: ");
915 scanf("%I64X", &addr);
916 tty->print("Calling hsfind(0x%I64X)\n", addr);
917 hsfind(addr);
918 break;
919 default:
920 case CMDID_ILLEGAL:
921 break;
922 }
923 }
924 }
925 }
926 }
927 }
928 #endif
930 #endif // !PRODUCT