# HG changeset patch # User jmasa # Date 1348002906 25200 # Node ID a00f5de57d3055e9485d41e041d4d72fbb2824fe # Parent 81163e1274d70b12b9a4383de007c16a446621ab 7197557: NPG: nsk/sysdict/vm/stress/chain/chain004 hangs intermittently Reviewed-by: johnc, ysr diff -r 81163e1274d7 -r a00f5de57d30 hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp --- 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. diff -r 81163e1274d7 -r a00f5de57d30 hotspot/src/share/vm/memory/collectorPolicy.cpp --- 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(); diff -r 81163e1274d7 -r a00f5de57d30 hotspot/src/share/vm/memory/metaspace.cpp --- 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 { diff -r 81163e1274d7 -r a00f5de57d30 hotspot/src/share/vm/memory/metaspace.hpp --- 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;