8027630: SIGSEGV in const char*Klass::external_name()
authorsla
Mon, 18 Nov 2013 10:20:13 +0100
changeset 21735 379ba90c3dc4
parent 21734 440a9598dc23
child 21736 ef8da7738ad4
8027630: SIGSEGV in const char*Klass::external_name() Reviewed-by: coleenp, sspitsyn, mgronlun
hotspot/src/share/vm/classfile/metadataOnStackMark.cpp
hotspot/src/share/vm/services/threadService.cpp
hotspot/src/share/vm/services/threadService.hpp
--- a/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp	Fri Nov 15 17:20:22 2013 -0500
+++ b/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp	Mon Nov 18 10:20:13 2013 +0100
@@ -30,6 +30,7 @@
 #include "prims/jvmtiImpl.hpp"
 #include "runtime/synchronizer.hpp"
 #include "runtime/thread.hpp"
+#include "services/threadService.hpp"
 #include "utilities/growableArray.hpp"
 
 
@@ -50,6 +51,7 @@
   CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
   CompileBroker::mark_on_stack();
   JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
+  ThreadService::metadata_do(Metadata::mark_on_stack);
 }
 
 MetadataOnStackMark::~MetadataOnStackMark() {
--- a/hotspot/src/share/vm/services/threadService.cpp	Fri Nov 15 17:20:22 2013 -0500
+++ b/hotspot/src/share/vm/services/threadService.cpp	Mon Nov 18 10:20:13 2013 +0100
@@ -200,6 +200,12 @@
   }
 }
 
+void ThreadService::metadata_do(void f(Metadata*)) {
+  for (ThreadDumpResult* dump = _threaddump_list; dump != NULL; dump = dump->next()) {
+    dump->metadata_do(f);
+  }
+}
+
 void ThreadService::add_thread_dump(ThreadDumpResult* dump) {
   MutexLocker ml(Management_lock);
   if (_threaddump_list == NULL) {
@@ -451,9 +457,16 @@
   }
 }
 
+void ThreadDumpResult::metadata_do(void f(Metadata*)) {
+  for (ThreadSnapshot* ts = _snapshots; ts != NULL; ts = ts->next()) {
+    ts->metadata_do(f);
+  }
+}
+
 StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) {
   _method = jvf->method();
   _bci = jvf->bci();
+  _class_holder = _method->method_holder()->klass_holder();
   _locked_monitors = NULL;
   if (with_lock_info) {
     ResourceMark rm;
@@ -477,6 +490,11 @@
       f->do_oop((oop*) _locked_monitors->adr_at(i));
     }
   }
+  f->do_oop(&_class_holder);
+}
+
+void StackFrameInfo::metadata_do(void f(Metadata*)) {
+  f(_method);
 }
 
 void StackFrameInfo::print_on(outputStream* st) const {
@@ -620,6 +638,14 @@
   }
 }
 
+void ThreadStackTrace::metadata_do(void f(Metadata*)) {
+  int length = _frames->length();
+  for (int i = 0; i < length; i++) {
+    _frames->at(i)->metadata_do(f);
+  }
+}
+
+
 ConcurrentLocksDump::~ConcurrentLocksDump() {
   if (_retain_map_on_free) {
     return;
@@ -823,6 +849,13 @@
   }
 }
 
+void ThreadSnapshot::metadata_do(void f(Metadata*)) {
+  if (_stack_trace != NULL) {
+    _stack_trace->metadata_do(f);
+  }
+}
+
+
 DeadlockCycle::DeadlockCycle() {
   _is_deadlock = false;
   _threads = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JavaThread*>(INITIAL_ARRAY_SIZE, true);
--- a/hotspot/src/share/vm/services/threadService.hpp	Fri Nov 15 17:20:22 2013 -0500
+++ b/hotspot/src/share/vm/services/threadService.hpp	Mon Nov 18 10:20:13 2013 +0100
@@ -113,6 +113,7 @@
 
   // GC support
   static void   oops_do(OopClosure* f);
+  static void   metadata_do(void f(Metadata*));
 };
 
 // Per-thread Statistics for synchronization
@@ -242,6 +243,7 @@
   void        dump_stack_at_safepoint(int max_depth, bool with_locked_monitors);
   void        set_concurrent_locks(ThreadConcurrentLocks* l) { _concurrent_locks = l; }
   void        oops_do(OopClosure* f);
+  void        metadata_do(void f(Metadata*));
 };
 
 class ThreadStackTrace : public CHeapObj<mtInternal> {
@@ -265,6 +267,7 @@
   void            dump_stack_at_safepoint(int max_depth);
   Handle          allocate_fill_stack_trace_element_array(TRAPS);
   void            oops_do(OopClosure* f);
+  void            metadata_do(void f(Metadata*));
   GrowableArray<oop>* jni_locked_monitors() { return _jni_locked_monitors; }
   int             num_jni_locked_monitors() { return (_jni_locked_monitors != NULL ? _jni_locked_monitors->length() : 0); }
 
@@ -280,6 +283,9 @@
   Method*             _method;
   int                 _bci;
   GrowableArray<oop>* _locked_monitors; // list of object monitors locked by this frame
+  // We need to save the mirrors in the backtrace to keep the class
+  // from being unloaded while we still have this stack trace.
+  oop                 _class_holder;
 
  public:
 
@@ -289,9 +295,10 @@
       delete _locked_monitors;
     }
   };
-  Method* method() const       { return _method; }
+  Method*   method() const       { return _method; }
   int       bci()    const       { return _bci; }
   void      oops_do(OopClosure* f);
+  void      metadata_do(void f(Metadata*));
 
   int       num_locked_monitors()       { return (_locked_monitors != NULL ? _locked_monitors->length() : 0); }
   GrowableArray<oop>* locked_monitors() { return _locked_monitors; }
@@ -354,6 +361,7 @@
   int                  num_snapshots()                  { return _num_snapshots; }
   ThreadSnapshot*      snapshots()                      { return _snapshots; }
   void                 oops_do(OopClosure* f);
+  void                 metadata_do(void f(Metadata*));
 };
 
 class DeadlockCycle : public CHeapObj<mtInternal> {