hotspot/src/share/vm/runtime/os.cpp
changeset 6176 4d9030fe341f
parent 5922 883ecb03d008
child 7108 4f87b92f3060
--- 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