--- a/hotspot/src/share/vm/runtime/os.cpp Wed Jul 28 17:57:43 2010 -0400
+++ b/hotspot/src/share/vm/runtime/os.cpp Tue Aug 03 08:13:38 2010 -0400
@@ -735,6 +735,152 @@
st->print_cr("elapsed time: %d seconds", (int)t);
}
+// moved from debug.cpp (used to be find()) but still called from there
+// The print_pc parameter is only set by the debug code in one case
+void os::print_location(outputStream* st, intptr_t x, bool print_pc) {
+ address addr = (address)x;
+ CodeBlob* b = CodeCache::find_blob_unsafe(addr);
+ if (b != NULL) {
+ if (b->is_buffer_blob()) {
+ // the interpreter is generated into a buffer blob
+ InterpreterCodelet* i = Interpreter::codelet_containing(addr);
+ if (i != NULL) {
+ i->print_on(st);
+ return;
+ }
+ if (Interpreter::contains(addr)) {
+ st->print_cr(INTPTR_FORMAT " is pointing into interpreter code"
+ " (not bytecode specific)", addr);
+ return;
+ }
+ //
+ if (AdapterHandlerLibrary::contains(b)) {
+ st->print_cr("Printing AdapterHandler");
+ AdapterHandlerLibrary::print_handler_on(st, b);
+ }
+ // the stubroutines are generated into a buffer blob
+ StubCodeDesc* d = StubCodeDesc::desc_for(addr);
+ if (d != NULL) {
+ d->print_on(st);
+ if (print_pc) st->cr();
+ return;
+ }
+ if (StubRoutines::contains(addr)) {
+ st->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) "
+ "stub routine", addr);
+ return;
+ }
+ // the InlineCacheBuffer is using stubs generated into a buffer blob
+ if (InlineCacheBuffer::contains(addr)) {
+ st->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr);
+ return;
+ }
+ VtableStub* v = VtableStubs::stub_containing(addr);
+ if (v != NULL) {
+ v->print_on(st);
+ return;
+ }
+ }
+ if (print_pc && b->is_nmethod()) {
+ ResourceMark rm;
+ st->print("%#p: Compiled ", addr);
+ ((nmethod*)b)->method()->print_value_on(st);
+ st->print(" = (CodeBlob*)" INTPTR_FORMAT, b);
+ st->cr();
+ return;
+ }
+ if ( b->is_nmethod()) {
+ if (b->is_zombie()) {
+ st->print_cr(INTPTR_FORMAT " is zombie nmethod", b);
+ } else if (b->is_not_entrant()) {
+ st->print_cr(INTPTR_FORMAT " is non-entrant nmethod", b);
+ }
+ }
+ b->print_on(st);
+ return;
+ }
+
+ if (Universe::heap()->is_in(addr)) {
+ HeapWord* p = Universe::heap()->block_start(addr);
+ bool print = false;
+ // If we couldn't find it it just may mean that heap wasn't parseable
+ // See if we were just given an oop directly
+ if (p != NULL && Universe::heap()->block_is_obj(p)) {
+ print = true;
+ } else if (p == NULL && ((oopDesc*)addr)->is_oop()) {
+ p = (HeapWord*) addr;
+ print = true;
+ }
+ if (print) {
+ oop(p)->print_on(st);
+ if (p != (HeapWord*)x && oop(p)->is_constMethod() &&
+ constMethodOop(p)->contains(addr)) {
+ Thread *thread = Thread::current();
+ HandleMark hm(thread);
+ methodHandle mh (thread, constMethodOop(p)->method());
+ if (!mh->is_native()) {
+ st->print_cr("bci_from(%p) = %d; print_codes():",
+ addr, mh->bci_from(address(x)));
+ mh->print_codes_on(st);
+ }
+ }
+ return;
+ }
+ } else {
+ if (Universe::heap()->is_in_reserved(addr)) {
+ st->print_cr(INTPTR_FORMAT " is an unallocated location "
+ "in the heap", addr);
+ return;
+ }
+ }
+ if (JNIHandles::is_global_handle((jobject) addr)) {
+ st->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
+ return;
+ }
+ if (JNIHandles::is_weak_global_handle((jobject) addr)) {
+ st->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr);
+ return;
+ }
+#ifndef PRODUCT
+ // we don't keep the block list in product mode
+ if (JNIHandleBlock::any_contains((jobject) addr)) {
+ st->print_cr(INTPTR_FORMAT " is a local jni handle", addr);
+ return;
+ }
+#endif
+
+ for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
+ // Check for privilege stack
+ if (thread->privileged_stack_top() != NULL &&
+ thread->privileged_stack_top()->contains(addr)) {
+ st->print_cr(INTPTR_FORMAT " is pointing into the privilege stack "
+ "for thread: " INTPTR_FORMAT, addr, thread);
+ thread->print_on(st);
+ return;
+ }
+ // If the addr is a java thread print information about that.
+ if (addr == (address)thread) {
+ thread->print_on(st);
+ return;
+ }
+ // If the addr is in the stack region for this thread then report that
+ // and print thread info
+ if (thread->stack_base() >= addr &&
+ addr > (thread->stack_base() - thread->stack_size())) {
+ st->print_cr(INTPTR_FORMAT " is pointing into the stack for thread: "
+ INTPTR_FORMAT, addr, thread);
+ thread->print_on(st);
+ return;
+ }
+
+ }
+ // Try an OS specific find
+ if (os::find(addr, st)) {
+ return;
+ }
+
+ st->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr);
+}
// Looks like all platforms except IA64 can use the same function to check
// if C stack is walkable beyond current frame. The check for fp() is not