aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #ifndef SHARE_VM_MEMORY_GCLOCKER_HPP aoqi@0: #define SHARE_VM_MEMORY_GCLOCKER_HPP aoqi@0: aoqi@0: #include "gc_interface/collectedHeap.hpp" aoqi@0: #include "memory/genCollectedHeap.hpp" aoqi@0: #include "memory/universe.hpp" aoqi@0: #include "oops/oop.hpp" aoqi@0: #include "runtime/thread.inline.hpp" aoqi@0: #ifdef TARGET_OS_FAMILY_linux aoqi@0: # include "os_linux.inline.hpp" aoqi@0: #endif aoqi@0: #ifdef TARGET_OS_FAMILY_solaris aoqi@0: # include "os_solaris.inline.hpp" aoqi@0: #endif aoqi@0: #ifdef TARGET_OS_FAMILY_windows aoqi@0: # include "os_windows.inline.hpp" aoqi@0: #endif aoqi@0: #ifdef TARGET_OS_FAMILY_bsd aoqi@0: # include "os_bsd.inline.hpp" aoqi@0: #endif aoqi@0: aoqi@0: // The direct lock/unlock calls do not force a collection if an unlock aoqi@0: // decrements the count to zero. Avoid calling these if at all possible. aoqi@0: aoqi@0: class GC_locker: public AllStatic { aoqi@0: private: aoqi@0: // The _jni_lock_count keeps track of the number of threads that are aoqi@0: // currently in a critical region. It's only kept up to date when aoqi@0: // _needs_gc is true. The current value is computed during aoqi@0: // safepointing and decremented during the slow path of GC_locker aoqi@0: // unlocking. aoqi@0: static volatile jint _jni_lock_count; // number of jni active instances. aoqi@0: static volatile bool _needs_gc; // heap is filling, we need a GC aoqi@0: // note: bool is typedef'd as jint aoqi@0: static volatile bool _doing_gc; // unlock_critical() is doing a GC aoqi@0: aoqi@0: #ifdef ASSERT aoqi@0: // This lock count is updated for all operations and is used to aoqi@0: // validate the jni_lock_count that is computed during safepoints. aoqi@0: static volatile jint _debug_jni_lock_count; aoqi@0: #endif aoqi@0: aoqi@0: // At a safepoint, visit all threads and count the number of active aoqi@0: // critical sections. This is used to ensure that all active aoqi@0: // critical sections are exited before a new one is started. aoqi@0: static void verify_critical_count() NOT_DEBUG_RETURN; aoqi@0: aoqi@0: static void jni_lock(JavaThread* thread); aoqi@0: static void jni_unlock(JavaThread* thread); aoqi@0: aoqi@0: static bool is_active_internal() { aoqi@0: verify_critical_count(); aoqi@0: return _jni_lock_count > 0; aoqi@0: } aoqi@0: aoqi@0: public: aoqi@0: // Accessors aoqi@0: static bool is_active() { aoqi@0: assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint"); aoqi@0: return is_active_internal(); aoqi@0: } aoqi@0: static bool needs_gc() { return _needs_gc; } aoqi@0: aoqi@0: // Shorthand aoqi@0: static bool is_active_and_needs_gc() { aoqi@0: // Use is_active_internal since _needs_gc can change from true to aoqi@0: // false outside of a safepoint, triggering the assert in aoqi@0: // is_active. aoqi@0: return needs_gc() && is_active_internal(); aoqi@0: } aoqi@0: aoqi@0: // In debug mode track the locking state at all times aoqi@0: static void increment_debug_jni_lock_count() { aoqi@0: #ifdef ASSERT aoqi@0: assert(_debug_jni_lock_count >= 0, "bad value"); aoqi@0: Atomic::inc(&_debug_jni_lock_count); aoqi@0: #endif aoqi@0: } aoqi@0: static void decrement_debug_jni_lock_count() { aoqi@0: #ifdef ASSERT aoqi@0: assert(_debug_jni_lock_count > 0, "bad value"); aoqi@0: Atomic::dec(&_debug_jni_lock_count); aoqi@0: #endif aoqi@0: } aoqi@0: aoqi@0: // Set the current lock count aoqi@0: static void set_jni_lock_count(int count) { aoqi@0: _jni_lock_count = count; aoqi@0: verify_critical_count(); aoqi@0: } aoqi@0: aoqi@0: // Sets _needs_gc if is_active() is true. Returns is_active(). aoqi@0: static bool check_active_before_gc(); aoqi@0: aoqi@0: // Stalls the caller (who should not be in a jni critical section) aoqi@0: // until needs_gc() clears. Note however that needs_gc() may be aoqi@0: // set at a subsequent safepoint and/or cleared under the aoqi@0: // JNICritical_lock, so the caller may not safely assert upon aoqi@0: // return from this method that "!needs_gc()" since that is aoqi@0: // not a stable predicate. aoqi@0: static void stall_until_clear(); aoqi@0: aoqi@0: // The following two methods are used for JNI critical regions. aoqi@0: // If we find that we failed to perform a GC because the GC_locker aoqi@0: // was active, arrange for one as soon as possible by allowing aoqi@0: // all threads in critical regions to complete, but not allowing aoqi@0: // other critical regions to be entered. The reasons for that are: aoqi@0: // 1) a GC request won't be starved by overlapping JNI critical aoqi@0: // region activities, which can cause unnecessary OutOfMemory errors. aoqi@0: // 2) even if allocation requests can still be satisfied before GC locker aoqi@0: // becomes inactive, for example, in tenured generation possibly with aoqi@0: // heap expansion, those allocations can trigger lots of safepointing aoqi@0: // attempts (ineffective GC attempts) and require Heap_lock which aoqi@0: // slow down allocations tremendously. aoqi@0: // aoqi@0: // Note that critical regions can be nested in a single thread, so aoqi@0: // we must allow threads already in critical regions to continue. aoqi@0: // aoqi@0: // JNI critical regions are the only participants in this scheme aoqi@0: // because they are, by spec, well bounded while in a critical region. aoqi@0: // aoqi@0: // Each of the following two method is split into a fast path and a aoqi@0: // slow path. JNICritical_lock is only grabbed in the slow path. aoqi@0: // _needs_gc is initially false and every java thread will go aoqi@0: // through the fast path, which simply increments or decrements the aoqi@0: // current thread's critical count. When GC happens at a safepoint, aoqi@0: // GC_locker::is_active() is checked. Since there is no safepoint in aoqi@0: // the fast path of lock_critical() and unlock_critical(), there is aoqi@0: // no race condition between the fast path and GC. After _needs_gc aoqi@0: // is set at a safepoint, every thread will go through the slow path aoqi@0: // after the safepoint. Since after a safepoint, each of the aoqi@0: // following two methods is either entered from the method entry and aoqi@0: // falls into the slow path, or is resumed from the safepoints in aoqi@0: // the method, which only exist in the slow path. So when _needs_gc aoqi@0: // is set, the slow path is always taken, till _needs_gc is cleared. aoqi@0: static void lock_critical(JavaThread* thread); aoqi@0: static void unlock_critical(JavaThread* thread); aoqi@0: aoqi@0: static address needs_gc_address() { return (address) &_needs_gc; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: // A No_GC_Verifier object can be placed in methods where one assumes that aoqi@0: // no garbage collection will occur. The destructor will verify this property aoqi@0: // unless the constructor is called with argument false (not verifygc). aoqi@0: // aoqi@0: // The check will only be done in debug mode and if verifygc true. aoqi@0: aoqi@0: class No_GC_Verifier: public StackObj { aoqi@0: friend class Pause_No_GC_Verifier; aoqi@0: aoqi@0: protected: aoqi@0: bool _verifygc; aoqi@0: unsigned int _old_invocations; aoqi@0: aoqi@0: public: aoqi@0: #ifdef ASSERT aoqi@0: No_GC_Verifier(bool verifygc = true); aoqi@0: ~No_GC_Verifier(); aoqi@0: #else aoqi@0: No_GC_Verifier(bool verifygc = true) {} aoqi@0: ~No_GC_Verifier() {} aoqi@0: #endif aoqi@0: }; aoqi@0: aoqi@0: // A Pause_No_GC_Verifier is used to temporarily pause the behavior aoqi@0: // of a No_GC_Verifier object. If we are not in debug mode or if the aoqi@0: // No_GC_Verifier object has a _verifygc value of false, then there aoqi@0: // is nothing to do. aoqi@0: aoqi@0: class Pause_No_GC_Verifier: public StackObj { aoqi@0: private: aoqi@0: No_GC_Verifier * _ngcv; aoqi@0: aoqi@0: public: aoqi@0: #ifdef ASSERT aoqi@0: Pause_No_GC_Verifier(No_GC_Verifier * ngcv); aoqi@0: ~Pause_No_GC_Verifier(); aoqi@0: #else aoqi@0: Pause_No_GC_Verifier(No_GC_Verifier * ngcv) {} aoqi@0: ~Pause_No_GC_Verifier() {} aoqi@0: #endif aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: // A No_Safepoint_Verifier object will throw an assertion failure if aoqi@0: // the current thread passes a possible safepoint while this object is aoqi@0: // instantiated. A safepoint, will either be: an oop allocation, blocking aoqi@0: // on a Mutex or JavaLock, or executing a VM operation. aoqi@0: // aoqi@0: // If StrictSafepointChecks is turned off, it degrades into a No_GC_Verifier aoqi@0: // aoqi@0: class No_Safepoint_Verifier : public No_GC_Verifier { aoqi@0: friend class Pause_No_Safepoint_Verifier; aoqi@0: aoqi@0: private: aoqi@0: bool _activated; aoqi@0: Thread *_thread; aoqi@0: public: aoqi@0: #ifdef ASSERT aoqi@0: No_Safepoint_Verifier(bool activated = true, bool verifygc = true ) : aoqi@0: No_GC_Verifier(verifygc), aoqi@0: _activated(activated) { aoqi@0: _thread = Thread::current(); aoqi@0: if (_activated) { aoqi@0: _thread->_allow_allocation_count++; aoqi@0: _thread->_allow_safepoint_count++; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: ~No_Safepoint_Verifier() { aoqi@0: if (_activated) { aoqi@0: _thread->_allow_allocation_count--; aoqi@0: _thread->_allow_safepoint_count--; aoqi@0: } aoqi@0: } aoqi@0: #else aoqi@0: No_Safepoint_Verifier(bool activated = true, bool verifygc = true) : No_GC_Verifier(verifygc){} aoqi@0: ~No_Safepoint_Verifier() {} aoqi@0: #endif aoqi@0: }; aoqi@0: aoqi@0: // A Pause_No_Safepoint_Verifier is used to temporarily pause the aoqi@0: // behavior of a No_Safepoint_Verifier object. If we are not in debug aoqi@0: // mode then there is nothing to do. If the No_Safepoint_Verifier aoqi@0: // object has an _activated value of false, then there is nothing to aoqi@0: // do for safepoint and allocation checking, but there may still be aoqi@0: // something to do for the underlying No_GC_Verifier object. aoqi@0: aoqi@0: class Pause_No_Safepoint_Verifier : public Pause_No_GC_Verifier { aoqi@0: private: aoqi@0: No_Safepoint_Verifier * _nsv; aoqi@0: aoqi@0: public: aoqi@0: #ifdef ASSERT aoqi@0: Pause_No_Safepoint_Verifier(No_Safepoint_Verifier * nsv) aoqi@0: : Pause_No_GC_Verifier(nsv) { aoqi@0: aoqi@0: _nsv = nsv; aoqi@0: if (_nsv->_activated) { aoqi@0: _nsv->_thread->_allow_allocation_count--; aoqi@0: _nsv->_thread->_allow_safepoint_count--; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: ~Pause_No_Safepoint_Verifier() { aoqi@0: if (_nsv->_activated) { aoqi@0: _nsv->_thread->_allow_allocation_count++; aoqi@0: _nsv->_thread->_allow_safepoint_count++; aoqi@0: } aoqi@0: } aoqi@0: #else aoqi@0: Pause_No_Safepoint_Verifier(No_Safepoint_Verifier * nsv) aoqi@0: : Pause_No_GC_Verifier(nsv) {} aoqi@0: ~Pause_No_Safepoint_Verifier() {} aoqi@0: #endif aoqi@0: }; aoqi@0: aoqi@0: // A SkipGCALot object is used to elide the usual effect of gc-a-lot aoqi@0: // over a section of execution by a thread. Currently, it's used only to aoqi@0: // prevent re-entrant calls to GC. aoqi@0: class SkipGCALot : public StackObj { aoqi@0: private: aoqi@0: bool _saved; aoqi@0: Thread* _t; aoqi@0: aoqi@0: public: aoqi@0: #ifdef ASSERT aoqi@0: SkipGCALot(Thread* t) : _t(t) { aoqi@0: _saved = _t->skip_gcalot(); aoqi@0: _t->set_skip_gcalot(true); aoqi@0: } aoqi@0: aoqi@0: ~SkipGCALot() { aoqi@0: assert(_t->skip_gcalot(), "Save-restore protocol invariant"); aoqi@0: _t->set_skip_gcalot(_saved); aoqi@0: } aoqi@0: #else aoqi@0: SkipGCALot(Thread* t) { } aoqi@0: ~SkipGCALot() { } aoqi@0: #endif aoqi@0: }; aoqi@0: aoqi@0: // JRT_LEAF currently can be called from either _thread_in_Java or aoqi@0: // _thread_in_native mode. In _thread_in_native, it is ok aoqi@0: // for another thread to trigger GC. The rest of the JRT_LEAF aoqi@0: // rules apply. aoqi@0: class JRT_Leaf_Verifier : public No_Safepoint_Verifier { aoqi@0: static bool should_verify_GC(); aoqi@0: public: aoqi@0: #ifdef ASSERT aoqi@0: JRT_Leaf_Verifier(); aoqi@0: ~JRT_Leaf_Verifier(); aoqi@0: #else aoqi@0: JRT_Leaf_Verifier() {} aoqi@0: ~JRT_Leaf_Verifier() {} aoqi@0: #endif aoqi@0: }; aoqi@0: aoqi@0: // A No_Alloc_Verifier object can be placed in methods where one assumes that aoqi@0: // no allocation will occur. The destructor will verify this property aoqi@0: // unless the constructor is called with argument false (not activated). aoqi@0: // aoqi@0: // The check will only be done in debug mode and if activated. aoqi@0: // Note: this only makes sense at safepoints (otherwise, other threads may aoqi@0: // allocate concurrently.) aoqi@0: aoqi@0: class No_Alloc_Verifier : public StackObj { aoqi@0: private: aoqi@0: bool _activated; aoqi@0: aoqi@0: public: aoqi@0: #ifdef ASSERT aoqi@0: No_Alloc_Verifier(bool activated = true) { aoqi@0: _activated = activated; aoqi@0: if (_activated) Thread::current()->_allow_allocation_count++; aoqi@0: } aoqi@0: aoqi@0: ~No_Alloc_Verifier() { aoqi@0: if (_activated) Thread::current()->_allow_allocation_count--; aoqi@0: } aoqi@0: #else aoqi@0: No_Alloc_Verifier(bool activated = true) {} aoqi@0: ~No_Alloc_Verifier() {} aoqi@0: #endif aoqi@0: }; aoqi@0: aoqi@0: #endif // SHARE_VM_MEMORY_GCLOCKER_HPP