src/hotspot/share/gc/shared/gcLocker.cpp
changeset 49594 898ef81cbc0e
parent 48105 8d15b1369c7a
child 54645 05aaccf7d558
equal deleted inserted replaced
49593:4dd58ecc9912 49594:898ef81cbc0e
    22  *
    22  *
    23  */
    23  */
    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.hpp"
    28 #include "memory/resourceArea.hpp"
    28 #include "memory/resourceArea.hpp"
    29 #include "logging/log.hpp"
    29 #include "logging/log.hpp"
    30 #include "runtime/atomic.hpp"
    30 #include "runtime/atomic.hpp"
       
    31 #include "runtime/safepoint.hpp"
    31 #include "runtime/thread.inline.hpp"
    32 #include "runtime/thread.inline.hpp"
    32 #include "runtime/threadSMR.hpp"
    33 #include "runtime/threadSMR.hpp"
    33 
    34 
    34 volatile jint GCLocker::_jni_lock_count = 0;
    35 volatile jint GCLocker::_jni_lock_count = 0;
    35 volatile bool GCLocker::_needs_gc       = false;
    36 volatile bool GCLocker::_needs_gc       = false;
    81   Log(gc, jni) log;
    82   Log(gc, jni) log;
    82   if (log.is_debug()) {
    83   if (log.is_debug()) {
    83     ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
    84     ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
    84     log.debug("%s Thread \"%s\" %d locked.", msg, Thread::current()->name(), _jni_lock_count);
    85     log.debug("%s Thread \"%s\" %d locked.", msg, Thread::current()->name(), _jni_lock_count);
    85   }
    86   }
       
    87 }
       
    88 
       
    89 bool GCLocker::is_at_safepoint() {
       
    90   return SafepointSynchronize::is_at_safepoint();
    86 }
    91 }
    87 
    92 
    88 bool GCLocker::check_active_before_gc() {
    93 bool GCLocker::check_active_before_gc() {
    89   assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
    94   assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
    90   if (is_active() && !_needs_gc) {
    95   if (is_active() && !_needs_gc) {
   143     _doing_gc = false;
   148     _doing_gc = false;
   144     _needs_gc = false;
   149     _needs_gc = false;
   145     JNICritical_lock->notify_all();
   150     JNICritical_lock->notify_all();
   146   }
   151   }
   147 }
   152 }
   148 
       
   149 // Implementation of NoGCVerifier
       
   150 
       
   151 #ifdef ASSERT
       
   152 
       
   153 NoGCVerifier::NoGCVerifier(bool verifygc) {
       
   154   _verifygc = verifygc;
       
   155   if (_verifygc) {
       
   156     CollectedHeap* h = Universe::heap();
       
   157     assert(!h->is_gc_active(), "GC active during NoGCVerifier");
       
   158     _old_invocations = h->total_collections();
       
   159   }
       
   160 }
       
   161 
       
   162 
       
   163 NoGCVerifier::~NoGCVerifier() {
       
   164   if (_verifygc) {
       
   165     CollectedHeap* h = Universe::heap();
       
   166     assert(!h->is_gc_active(), "GC active during NoGCVerifier");
       
   167     if (_old_invocations != h->total_collections()) {
       
   168       fatal("collection in a NoGCVerifier secured function");
       
   169     }
       
   170   }
       
   171 }
       
   172 
       
   173 PauseNoGCVerifier::PauseNoGCVerifier(NoGCVerifier * ngcv) {
       
   174   _ngcv = ngcv;
       
   175   if (_ngcv->_verifygc) {
       
   176     // if we were verifying, then make sure that nothing is
       
   177     // wrong before we "pause" verification
       
   178     CollectedHeap* h = Universe::heap();
       
   179     assert(!h->is_gc_active(), "GC active during NoGCVerifier");
       
   180     if (_ngcv->_old_invocations != h->total_collections()) {
       
   181       fatal("collection in a NoGCVerifier secured function");
       
   182     }
       
   183   }
       
   184 }
       
   185 
       
   186 
       
   187 PauseNoGCVerifier::~PauseNoGCVerifier() {
       
   188   if (_ngcv->_verifygc) {
       
   189     // if we were verifying before, then reenable verification
       
   190     CollectedHeap* h = Universe::heap();
       
   191     assert(!h->is_gc_active(), "GC active during NoGCVerifier");
       
   192     _ngcv->_old_invocations = h->total_collections();
       
   193   }
       
   194 }
       
   195 
       
   196 
       
   197 // JRT_LEAF rules:
       
   198 // A JRT_LEAF method may not interfere with safepointing by
       
   199 //   1) acquiring or blocking on a Mutex or JavaLock - checked
       
   200 //   2) allocating heap memory - checked
       
   201 //   3) executing a VM operation - checked
       
   202 //   4) executing a system call (including malloc) that could block or grab a lock
       
   203 //   5) invoking GC
       
   204 //   6) reaching a safepoint
       
   205 //   7) running too long
       
   206 // Nor may any method it calls.
       
   207 JRTLeafVerifier::JRTLeafVerifier()
       
   208   : NoSafepointVerifier(true, JRTLeafVerifier::should_verify_GC())
       
   209 {
       
   210 }
       
   211 
       
   212 JRTLeafVerifier::~JRTLeafVerifier()
       
   213 {
       
   214 }
       
   215 
       
   216 bool JRTLeafVerifier::should_verify_GC() {
       
   217   switch (JavaThread::current()->thread_state()) {
       
   218   case _thread_in_Java:
       
   219     // is in a leaf routine, there must be no safepoint.
       
   220     return true;
       
   221   case _thread_in_native:
       
   222     // A native thread is not subject to safepoints.
       
   223     // Even while it is in a leaf routine, GC is ok
       
   224     return false;
       
   225   default:
       
   226     // Leaf routines cannot be called from other contexts.
       
   227     ShouldNotReachHere();
       
   228     return false;
       
   229   }
       
   230 }
       
   231 #endif