hotspot/src/share/vm/memory/gcLocker.cpp
changeset 23540 06f7d6e1f654
parent 22234 da823d78ad65
child 24351 61b33cc6d3cf
equal deleted inserted replaced
23539:6382fd0ea303 23540:06f7d6e1f654
    26 #include "memory/gcLocker.inline.hpp"
    26 #include "memory/gcLocker.inline.hpp"
    27 #include "memory/resourceArea.hpp"
    27 #include "memory/resourceArea.hpp"
    28 #include "memory/sharedHeap.hpp"
    28 #include "memory/sharedHeap.hpp"
    29 
    29 
    30 volatile jint GC_locker::_jni_lock_count = 0;
    30 volatile jint GC_locker::_jni_lock_count = 0;
    31 volatile jint GC_locker::_lock_count     = 0;
       
    32 volatile bool GC_locker::_needs_gc       = false;
    31 volatile bool GC_locker::_needs_gc       = false;
    33 volatile bool GC_locker::_doing_gc       = false;
    32 volatile bool GC_locker::_doing_gc       = false;
    34 
    33 
    35 #ifdef ASSERT
    34 #ifdef ASSERT
    36 volatile jint GC_locker::_debug_jni_lock_count = 0;
    35 volatile jint GC_locker::_debug_jni_lock_count = 0;
   100   // Block entering threads if we know at least one thread is in a
    99   // Block entering threads if we know at least one thread is in a
   101   // JNI critical region and we need a GC.
   100   // JNI critical region and we need a GC.
   102   // We check that at least one thread is in a critical region before
   101   // We check that at least one thread is in a critical region before
   103   // blocking because blocked threads are woken up by a thread exiting
   102   // blocking because blocked threads are woken up by a thread exiting
   104   // a JNI critical region.
   103   // a JNI critical region.
   105   while ((needs_gc() && is_jni_active()) || _doing_gc) {
   104   while (is_active_and_needs_gc() || _doing_gc) {
   106     JNICritical_lock->wait();
   105     JNICritical_lock->wait();
   107   }
   106   }
   108   thread->enter_critical();
   107   thread->enter_critical();
   109   _jni_lock_count++;
   108   _jni_lock_count++;
   110   increment_debug_jni_lock_count();
   109   increment_debug_jni_lock_count();
   114   assert(thread->in_last_critical(), "should be exiting critical region");
   113   assert(thread->in_last_critical(), "should be exiting critical region");
   115   MutexLocker mu(JNICritical_lock);
   114   MutexLocker mu(JNICritical_lock);
   116   _jni_lock_count--;
   115   _jni_lock_count--;
   117   decrement_debug_jni_lock_count();
   116   decrement_debug_jni_lock_count();
   118   thread->exit_critical();
   117   thread->exit_critical();
   119   if (needs_gc() && !is_jni_active()) {
   118   if (needs_gc() && !is_active_internal()) {
   120     // We're the last thread out. Cause a GC to occur.
   119     // We're the last thread out. Cause a GC to occur.
   121     // GC will also check is_active, so this check is not
   120     _doing_gc = true;
   122     // strictly needed. It's added here to make it clear that
   121     {
   123     // the GC will NOT be performed if any other caller
   122       // Must give up the lock while at a safepoint
   124     // of GC_locker::lock() still needs GC locked.
   123       MutexUnlocker munlock(JNICritical_lock);
   125     if (!is_active_internal()) {
   124       if (PrintJNIGCStalls && PrintGCDetails) {
   126       _doing_gc = true;
   125         ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
   127       {
   126         gclog_or_tty->print_cr("%.3f: Thread \"%s\" is performing GC after exiting critical section, %d locked",
   128         // Must give up the lock while at a safepoint
   127             gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
   129         MutexUnlocker munlock(JNICritical_lock);
       
   130         if (PrintJNIGCStalls && PrintGCDetails) {
       
   131           ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
       
   132           gclog_or_tty->print_cr("%.3f: Thread \"%s\" is performing GC after exiting critical section, %d locked",
       
   133                                  gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
       
   134         }
       
   135         Universe::heap()->collect(GCCause::_gc_locker);
       
   136       }
   128       }
   137       _doing_gc = false;
   129       Universe::heap()->collect(GCCause::_gc_locker);
   138     }
   130     }
   139 
   131     _doing_gc = false;
   140     _needs_gc = false;
   132     _needs_gc = false;
   141     JNICritical_lock->notify_all();
   133     JNICritical_lock->notify_all();
   142   }
   134   }
   143 }
   135 }
   144 
   136