hotspot/src/share/vm/gc/shared/gcLocker.cpp
changeset 35061 be6025ebffea
parent 30764 fec48bf5a827
child 35492 c8c0273e6b91
equal deleted inserted replaced
35060:382d0689141c 35061:be6025ebffea
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "gc/shared/collectedHeap.hpp"
    26 #include "gc/shared/collectedHeap.hpp"
    27 #include "gc/shared/gcLocker.inline.hpp"
    27 #include "gc/shared/gcLocker.inline.hpp"
    28 #include "memory/resourceArea.hpp"
    28 #include "memory/resourceArea.hpp"
       
    29 #include "logging/log.hpp"
    29 #include "runtime/atomic.inline.hpp"
    30 #include "runtime/atomic.inline.hpp"
    30 #include "runtime/thread.inline.hpp"
    31 #include "runtime/thread.inline.hpp"
    31 
    32 
    32 volatile jint GC_locker::_jni_lock_count = 0;
    33 volatile jint GC_locker::_jni_lock_count = 0;
    33 volatile bool GC_locker::_needs_gc       = false;
    34 volatile bool GC_locker::_needs_gc       = false;
    71   assert(_debug_jni_lock_count > 0, "bad value");
    72   assert(_debug_jni_lock_count > 0, "bad value");
    72   Atomic::dec(&_debug_jni_lock_count);
    73   Atomic::dec(&_debug_jni_lock_count);
    73 }
    74 }
    74 #endif
    75 #endif
    75 
    76 
       
    77 void GC_locker::log_debug_jni(const char* msg) {
       
    78   LogHandle(gc, jni) log;
       
    79   if (log.is_debug()) {
       
    80     ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
       
    81     log.debug("%s Thread \"%s\" %d locked.", msg, Thread::current()->name(), _jni_lock_count);
       
    82   }
       
    83 }
       
    84 
    76 bool GC_locker::check_active_before_gc() {
    85 bool GC_locker::check_active_before_gc() {
    77   assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
    86   assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
    78   if (is_active() && !_needs_gc) {
    87   if (is_active() && !_needs_gc) {
    79     verify_critical_count();
    88     verify_critical_count();
    80     _needs_gc = true;
    89     _needs_gc = true;
    81     if (PrintJNIGCStalls && PrintGCDetails) {
    90     log_debug_jni("Setting _needs_gc.");
    82       ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
       
    83       gclog_or_tty->print_cr("%.3f: Setting _needs_gc. Thread \"%s\" %d locked.",
       
    84                              gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
       
    85     }
       
    86 
       
    87   }
    91   }
    88   return is_active();
    92   return is_active();
    89 }
    93 }
    90 
    94 
    91 void GC_locker::stall_until_clear() {
    95 void GC_locker::stall_until_clear() {
    92   assert(!JavaThread::current()->in_critical(), "Would deadlock");
    96   assert(!JavaThread::current()->in_critical(), "Would deadlock");
    93   MutexLocker   ml(JNICritical_lock);
    97   MutexLocker   ml(JNICritical_lock);
    94 
    98 
    95   if (needs_gc()) {
    99   if (needs_gc()) {
    96     if (PrintJNIGCStalls && PrintGCDetails) {
   100     log_debug_jni("Allocation failed. Thread stalled by JNI critical section.");
    97       ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
       
    98       gclog_or_tty->print_cr("%.3f: Allocation failed. Thread \"%s\" is stalled by JNI critical section, %d locked.",
       
    99                              gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
       
   100     }
       
   101   }
   101   }
   102 
   102 
   103   // Wait for _needs_gc  to be cleared
   103   // Wait for _needs_gc  to be cleared
   104   while (needs_gc()) {
   104   while (needs_gc()) {
   105     JNICritical_lock->wait();
   105     JNICritical_lock->wait();
   132     // We're the last thread out. Cause a GC to occur.
   132     // We're the last thread out. Cause a GC to occur.
   133     _doing_gc = true;
   133     _doing_gc = true;
   134     {
   134     {
   135       // Must give up the lock while at a safepoint
   135       // Must give up the lock while at a safepoint
   136       MutexUnlocker munlock(JNICritical_lock);
   136       MutexUnlocker munlock(JNICritical_lock);
   137       if (PrintJNIGCStalls && PrintGCDetails) {
   137       log_debug_jni("Performing GC after exiting critical section.");
   138         ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
       
   139         gclog_or_tty->print_cr("%.3f: Thread \"%s\" is performing GC after exiting critical section, %d locked",
       
   140             gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
       
   141       }
       
   142       Universe::heap()->collect(GCCause::_gc_locker);
   138       Universe::heap()->collect(GCCause::_gc_locker);
   143     }
   139     }
   144     _doing_gc = false;
   140     _doing_gc = false;
   145     _needs_gc = false;
   141     _needs_gc = false;
   146     JNICritical_lock->notify_all();
   142     JNICritical_lock->notify_all();