7197557: NPG: nsk/sysdict/vm/stress/chain/chain004 hangs intermittently
authorjmasa
Tue, 18 Sep 2012 14:15:06 -0700
changeset 13755 a00f5de57d30
parent 13754 81163e1274d7
child 13756 3b72f3da8cd4
7197557: NPG: nsk/sysdict/vm/stress/chain/chain004 hangs intermittently Reviewed-by: johnc, ysr
hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp
hotspot/src/share/vm/memory/collectorPolicy.cpp
hotspot/src/share/vm/memory/metaspace.cpp
hotspot/src/share/vm/memory/metaspace.hpp
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Mon Sep 17 10:33:13 2012 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Tue Sep 18 14:15:06 2012 -0700
@@ -230,15 +230,9 @@
       // amount of the expansion.
       // This should work unless there really is no more space
       // or a MaxMetaspaceSize has been specified on the command line.
-      MetaspaceGC::set_expand_after_GC(true);
-      size_t before_inc = MetaspaceGC::capacity_until_GC();
-      size_t delta_words = MetaspaceGC::delta_capacity_until_GC(_size);
-      MetaspaceGC::inc_capacity_until_GC(delta_words);
-      if (PrintGCDetails && Verbose) {
-        gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
-          " to " SIZE_FORMAT, before_inc, MetaspaceGC::capacity_until_GC());
-  }
-      _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
+      _result =
+        _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype);
+
       if (do_cms_concurrent && _result == NULL) {
         // Rather than fail with a metaspace out-of-memory, do a full
         // GC for CMS.
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp	Mon Sep 17 10:33:13 2012 +0200
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp	Tue Sep 18 14:15:06 2012 -0700
@@ -743,6 +743,36 @@
   uint full_gc_count = 0;
 
   do {
+    MetaWord* result = NULL;
+    if (GC_locker::is_active_and_needs_gc()) {
+      // If the GC_locker is active, just expand and allocate.
+      // If that does not succeed, wait if this thread is not
+      // in a critical section itself.
+      result =
+        loader_data->metaspace_non_null()->expand_and_allocate(word_size,
+                                                               mdtype);
+      if (result != NULL) {
+        return result;
+      }
+      JavaThread* jthr = JavaThread::current();
+      if (!jthr->in_critical()) {
+        MutexUnlocker mul(Heap_lock);
+        // Wait for JNI critical section to be exited
+        GC_locker::stall_until_clear();
+        // The GC invoked by the last thread leaving the critical
+        // section will be a young collection and a full collection
+        // is (currently) needed for unloading classes so continue
+        // to the next iteration to get a full GC.
+        continue;
+      } else {
+        if (CheckJNICalls) {
+          fatal("Possible deadlock due to allocating while"
+                " in jni critical section");
+        }
+        return NULL;
+      }
+    }
+
     {  // Need lock to get self consistent gc_count's
       MutexLocker ml(Heap_lock);
       gc_count      = Universe::heap()->total_collections();
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Mon Sep 17 10:33:13 2012 +0200
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Tue Sep 18 14:15:06 2012 -0700
@@ -2843,6 +2843,21 @@
   }
 }
 
+MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) {
+  MetaWord* result;
+  MetaspaceGC::set_expand_after_GC(true);
+  size_t before_inc = MetaspaceGC::capacity_until_GC();
+  size_t delta_words = MetaspaceGC::delta_capacity_until_GC(word_size);
+  MetaspaceGC::inc_capacity_until_GC(delta_words);
+  if (PrintGCDetails && Verbose) {
+    gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
+      " to " SIZE_FORMAT, before_inc, MetaspaceGC::capacity_until_GC());
+  }
+  result = allocate(word_size, mdtype);
+
+  return result;
+}
+
 // Space allocated in the Metaspace.  This may
 // be across several metadata virtual spaces.
 char* Metaspace::bottom() const {
--- a/hotspot/src/share/vm/memory/metaspace.hpp	Mon Sep 17 10:33:13 2012 +0200
+++ b/hotspot/src/share/vm/memory/metaspace.hpp	Tue Sep 18 14:15:06 2012 -0700
@@ -130,8 +130,10 @@
 
   static MetaWord* allocate(ClassLoaderData* loader_data, size_t size,
                             bool read_only, MetadataType mdtype, TRAPS);
+  void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
 
-  void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
+  MetaWord* expand_and_allocate(size_t size,
+                                MetadataType mdtype);
 
 #ifndef PRODUCT
   bool contains(const void *ptr) const;