< 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 >