< prev index next >

src/share/vm/gc/shared/gcLocker.hpp

Print this page

        

*** 31,46 **** #include "oops/oop.hpp" // The direct lock/unlock calls do not force a collection if an unlock // decrements the count to zero. Avoid calling these if at all possible. ! class GC_locker: public AllStatic { private: // The _jni_lock_count keeps track of the number of threads that are // currently in a critical region. It's only kept up to date when // _needs_gc is true. The current value is computed during ! // safepointing and decremented during the slow path of GC_locker // unlocking. static volatile jint _jni_lock_count; // number of jni active instances. static volatile bool _needs_gc; // heap is filling, we need a GC // note: bool is typedef'd as jint static volatile bool _doing_gc; // unlock_critical() is doing a GC --- 31,46 ---- #include "oops/oop.hpp" // The direct lock/unlock calls do not force a collection if an unlock // decrements the count to zero. Avoid calling these if at all possible. ! class GCLocker: public AllStatic { private: // The _jni_lock_count keeps track of the number of threads that are // currently in a critical region. It's only kept up to date when // _needs_gc is true. The current value is computed during ! // safepointing and decremented during the slow path of GCLocker // unlocking. static volatile jint _jni_lock_count; // number of jni active instances. static volatile bool _needs_gc; // heap is filling, we need a GC // note: bool is typedef'd as jint static volatile bool _doing_gc; // unlock_critical() is doing a GC
*** 101,111 **** // return from this method that "!needs_gc()" since that is // not a stable predicate. static void stall_until_clear(); // The following two methods are used for JNI critical regions. ! // If we find that we failed to perform a GC because the GC_locker // was active, arrange for one as soon as possible by allowing // all threads in critical regions to complete, but not allowing // other critical regions to be entered. The reasons for that are: // 1) a GC request won't be starved by overlapping JNI critical // region activities, which can cause unnecessary OutOfMemory errors. --- 101,111 ---- // return from this method that "!needs_gc()" since that is // not a stable predicate. static void stall_until_clear(); // The following two methods are used for JNI critical regions. ! // If we find that we failed to perform a GC because the GCLocker // was active, arrange for one as soon as possible by allowing // all threads in critical regions to complete, but not allowing // other critical regions to be entered. The reasons for that are: // 1) a GC request won't be starved by overlapping JNI critical // region activities, which can cause unnecessary OutOfMemory errors.
*** 124,134 **** // Each of the following two method is split into a fast path and a // slow path. JNICritical_lock is only grabbed in the slow path. // _needs_gc is initially false and every java thread will go // through the fast path, which simply increments or decrements the // current thread's critical count. When GC happens at a safepoint, ! // GC_locker::is_active() is checked. Since there is no safepoint in // the fast path of lock_critical() and unlock_critical(), there is // no race condition between the fast path and GC. After _needs_gc // is set at a safepoint, every thread will go through the slow path // after the safepoint. Since after a safepoint, each of the // following two methods is either entered from the method entry and --- 124,134 ---- // Each of the following two method is split into a fast path and a // slow path. JNICritical_lock is only grabbed in the slow path. // _needs_gc is initially false and every java thread will go // through the fast path, which simply increments or decrements the // current thread's critical count. When GC happens at a safepoint, ! // GCLocker::is_active() is checked. Since there is no safepoint in // the fast path of lock_critical() and unlock_critical(), there is // no race condition between the fast path and GC. After _needs_gc // is set at a safepoint, every thread will go through the slow path // after the safepoint. Since after a safepoint, each of the // following two methods is either entered from the method entry and
*** 140,262 **** static address needs_gc_address() { return (address) &_needs_gc; } }; ! // A No_GC_Verifier object can be placed in methods where one assumes that // no garbage collection will occur. The destructor will verify this property // unless the constructor is called with argument false (not verifygc). // // The check will only be done in debug mode and if verifygc true. ! class No_GC_Verifier: public StackObj { ! friend class Pause_No_GC_Verifier; protected: bool _verifygc; unsigned int _old_invocations; public: #ifdef ASSERT ! No_GC_Verifier(bool verifygc = true); ! ~No_GC_Verifier(); #else ! No_GC_Verifier(bool verifygc = true) {} ! ~No_GC_Verifier() {} #endif }; ! // A Pause_No_GC_Verifier is used to temporarily pause the behavior ! // of a No_GC_Verifier object. If we are not in debug mode or if the ! // No_GC_Verifier object has a _verifygc value of false, then there // is nothing to do. ! class Pause_No_GC_Verifier: public StackObj { private: ! No_GC_Verifier * _ngcv; public: #ifdef ASSERT ! Pause_No_GC_Verifier(No_GC_Verifier * ngcv); ! ~Pause_No_GC_Verifier(); #else ! Pause_No_GC_Verifier(No_GC_Verifier * ngcv) {} ! ~Pause_No_GC_Verifier() {} #endif }; ! // A No_Safepoint_Verifier object will throw an assertion failure if // the current thread passes a possible safepoint while this object is // instantiated. A safepoint, will either be: an oop allocation, blocking // on a Mutex or JavaLock, or executing a VM operation. // ! // If StrictSafepointChecks is turned off, it degrades into a No_GC_Verifier // ! class No_Safepoint_Verifier : public No_GC_Verifier { ! friend class Pause_No_Safepoint_Verifier; private: bool _activated; Thread *_thread; public: #ifdef ASSERT ! No_Safepoint_Verifier(bool activated = true, bool verifygc = true ) : ! No_GC_Verifier(verifygc), _activated(activated) { _thread = Thread::current(); if (_activated) { _thread->_allow_allocation_count++; _thread->_allow_safepoint_count++; } } ! ~No_Safepoint_Verifier() { if (_activated) { _thread->_allow_allocation_count--; _thread->_allow_safepoint_count--; } } #else ! No_Safepoint_Verifier(bool activated = true, bool verifygc = true) : No_GC_Verifier(verifygc){} ! ~No_Safepoint_Verifier() {} #endif }; ! // A Pause_No_Safepoint_Verifier is used to temporarily pause the ! // behavior of a No_Safepoint_Verifier object. If we are not in debug ! // mode then there is nothing to do. If the No_Safepoint_Verifier // object has an _activated value of false, then there is nothing to // do for safepoint and allocation checking, but there may still be ! // something to do for the underlying No_GC_Verifier object. ! class Pause_No_Safepoint_Verifier : public Pause_No_GC_Verifier { private: ! No_Safepoint_Verifier * _nsv; public: #ifdef ASSERT ! Pause_No_Safepoint_Verifier(No_Safepoint_Verifier * nsv) ! : Pause_No_GC_Verifier(nsv) { _nsv = nsv; if (_nsv->_activated) { _nsv->_thread->_allow_allocation_count--; _nsv->_thread->_allow_safepoint_count--; } } ! ~Pause_No_Safepoint_Verifier() { if (_nsv->_activated) { _nsv->_thread->_allow_allocation_count++; _nsv->_thread->_allow_safepoint_count++; } } #else ! Pause_No_Safepoint_Verifier(No_Safepoint_Verifier * nsv) ! : Pause_No_GC_Verifier(nsv) {} ! ~Pause_No_Safepoint_Verifier() {} #endif }; // A SkipGCALot object is used to elide the usual effect of gc-a-lot // over a section of execution by a thread. Currently, it's used only to --- 140,262 ---- static address needs_gc_address() { return (address) &_needs_gc; } }; ! // A NoGCVerifier object can be placed in methods where one assumes that // no garbage collection will occur. The destructor will verify this property // unless the constructor is called with argument false (not verifygc). // // The check will only be done in debug mode and if verifygc true. ! class NoGCVerifier: public StackObj { ! friend class PauseNoGCVerifier; protected: bool _verifygc; unsigned int _old_invocations; public: #ifdef ASSERT ! NoGCVerifier(bool verifygc = true); ! ~NoGCVerifier(); #else ! NoGCVerifier(bool verifygc = true) {} ! ~NoGCVerifier() {} #endif }; ! // A PauseNoGCVerifier is used to temporarily pause the behavior ! // of a NoGCVerifier object. If we are not in debug mode or if the ! // NoGCVerifier object has a _verifygc value of false, then there // is nothing to do. ! class PauseNoGCVerifier: public StackObj { private: ! NoGCVerifier * _ngcv; public: #ifdef ASSERT ! PauseNoGCVerifier(NoGCVerifier * ngcv); ! ~PauseNoGCVerifier(); #else ! PauseNoGCVerifier(NoGCVerifier * ngcv) {} ! ~PauseNoGCVerifier() {} #endif }; ! // A NoSafepointVerifier object will throw an assertion failure if // the current thread passes a possible safepoint while this object is // instantiated. A safepoint, will either be: an oop allocation, blocking // on a Mutex or JavaLock, or executing a VM operation. // ! // If StrictSafepointChecks is turned off, it degrades into a NoGCVerifier // ! class NoSafepointVerifier : public NoGCVerifier { ! friend class PauseNoSafepointVerifier; private: bool _activated; Thread *_thread; public: #ifdef ASSERT ! NoSafepointVerifier(bool activated = true, bool verifygc = true ) : ! NoGCVerifier(verifygc), _activated(activated) { _thread = Thread::current(); if (_activated) { _thread->_allow_allocation_count++; _thread->_allow_safepoint_count++; } } ! ~NoSafepointVerifier() { if (_activated) { _thread->_allow_allocation_count--; _thread->_allow_safepoint_count--; } } #else ! NoSafepointVerifier(bool activated = true, bool verifygc = true) : NoGCVerifier(verifygc){} ! ~NoSafepointVerifier() {} #endif }; ! // A PauseNoSafepointVerifier is used to temporarily pause the ! // behavior of a NoSafepointVerifier object. If we are not in debug ! // mode then there is nothing to do. If the NoSafepointVerifier // object has an _activated value of false, then there is nothing to // do for safepoint and allocation checking, but there may still be ! // something to do for the underlying NoGCVerifier object. ! class PauseNoSafepointVerifier : public PauseNoGCVerifier { private: ! NoSafepointVerifier * _nsv; public: #ifdef ASSERT ! PauseNoSafepointVerifier(NoSafepointVerifier * nsv) ! : PauseNoGCVerifier(nsv) { _nsv = nsv; if (_nsv->_activated) { _nsv->_thread->_allow_allocation_count--; _nsv->_thread->_allow_safepoint_count--; } } ! ~PauseNoSafepointVerifier() { if (_nsv->_activated) { _nsv->_thread->_allow_allocation_count++; _nsv->_thread->_allow_safepoint_count++; } } #else ! PauseNoSafepointVerifier(NoSafepointVerifier * nsv) ! : PauseNoGCVerifier(nsv) {} ! ~PauseNoSafepointVerifier() {} #endif }; // A SkipGCALot object is used to elide the usual effect of gc-a-lot // over a section of execution by a thread. Currently, it's used only to
*** 285,330 **** // JRT_LEAF currently can be called from either _thread_in_Java or // _thread_in_native mode. In _thread_in_native, it is ok // for another thread to trigger GC. The rest of the JRT_LEAF // rules apply. ! class JRT_Leaf_Verifier : public No_Safepoint_Verifier { static bool should_verify_GC(); public: #ifdef ASSERT ! JRT_Leaf_Verifier(); ! ~JRT_Leaf_Verifier(); #else ! JRT_Leaf_Verifier() {} ! ~JRT_Leaf_Verifier() {} #endif }; ! // A No_Alloc_Verifier object can be placed in methods where one assumes that // no allocation will occur. The destructor will verify this property // unless the constructor is called with argument false (not activated). // // The check will only be done in debug mode and if activated. // Note: this only makes sense at safepoints (otherwise, other threads may // allocate concurrently.) ! class No_Alloc_Verifier : public StackObj { private: bool _activated; public: #ifdef ASSERT ! No_Alloc_Verifier(bool activated = true) { _activated = activated; if (_activated) Thread::current()->_allow_allocation_count++; } ! ~No_Alloc_Verifier() { if (_activated) Thread::current()->_allow_allocation_count--; } #else ! No_Alloc_Verifier(bool activated = true) {} ! ~No_Alloc_Verifier() {} #endif }; #endif // SHARE_VM_GC_SHARED_GCLOCKER_HPP --- 285,330 ---- // JRT_LEAF currently can be called from either _thread_in_Java or // _thread_in_native mode. In _thread_in_native, it is ok // for another thread to trigger GC. The rest of the JRT_LEAF // rules apply. ! class JRTLeafVerifier : public NoSafepointVerifier { static bool should_verify_GC(); public: #ifdef ASSERT ! JRTLeafVerifier(); ! ~JRTLeafVerifier(); #else ! JRTLeafVerifier() {} ! ~JRTLeafVerifier() {} #endif }; ! // A NoAllocVerifier object can be placed in methods where one assumes that // no allocation will occur. The destructor will verify this property // unless the constructor is called with argument false (not activated). // // The check will only be done in debug mode and if activated. // Note: this only makes sense at safepoints (otherwise, other threads may // allocate concurrently.) ! class NoAllocVerifier : public StackObj { private: bool _activated; public: #ifdef ASSERT ! NoAllocVerifier(bool activated = true) { _activated = activated; if (_activated) Thread::current()->_allow_allocation_count++; } ! ~NoAllocVerifier() { if (_activated) Thread::current()->_allow_allocation_count--; } #else ! NoAllocVerifier(bool activated = true) {} ! ~NoAllocVerifier() {} #endif }; #endif // SHARE_VM_GC_SHARED_GCLOCKER_HPP
< prev index next >