1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "memory/gcLocker.inline.hpp" 27 #include "memory/resourceArea.hpp" 28 #include "memory/sharedHeap.hpp" 29 30 volatile jint GC_locker::_jni_lock_count = 0; 31 volatile bool GC_locker::_needs_gc = false; 32 volatile bool GC_locker::_doing_gc = false; 33 34 #ifdef ASSERT 35 volatile jint GC_locker::_debug_jni_lock_count = 0; 36 #endif 37 38 39 #ifdef ASSERT 40 void GC_locker::verify_critical_count() { 41 if (SafepointSynchronize::is_at_safepoint()) { 42 assert(!needs_gc() || _debug_jni_lock_count == _jni_lock_count, "must agree"); 43 int count = 0; 44 // Count the number of threads with critical operations in progress 45 for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) { 46 if (thr->in_critical()) { 47 count++; 48 } 49 } 50 if (_jni_lock_count != count) { 51 tty->print_cr("critical counts don't match: %d != %d", _jni_lock_count, count); 52 for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) { 53 if (thr->in_critical()) { 54 tty->print_cr(INTPTR_FORMAT " in_critical %d", thr, thr->in_critical()); 55 } 56 } 57 } 58 assert(_jni_lock_count == count, "must be equal"); 59 } 60 } 61 #endif 62 63 bool GC_locker::check_active_before_gc() { 64 assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint"); 65 if (is_active() && !_needs_gc) { 66 verify_critical_count(); 67 _needs_gc = true; 68 if (PrintJNIGCStalls && PrintGCDetails) { 69 ResourceMark rm; // JavaThread::name() allocates to convert to UTF8 70 gclog_or_tty->print_cr("%.3f: Setting _needs_gc. Thread \"%s\" %d locked.", 71 gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count); 72 } 73 74 } 75 return is_active(); 76 } 77 78 void GC_locker::stall_until_clear() { 79 assert(!JavaThread::current()->in_critical(), "Would deadlock"); 80 MutexLocker ml(JNICritical_lock); 81 82 if (needs_gc()) { 83 if (PrintJNIGCStalls && PrintGCDetails) { 84 ResourceMark rm; // JavaThread::name() allocates to convert to UTF8 85 gclog_or_tty->print_cr("%.3f: Allocation failed. Thread \"%s\" is stalled by JNI critical section, %d locked.", 86 gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count); 87 } 88 } 89 90 // Wait for _needs_gc to be cleared 91 while (needs_gc()) { 92 JNICritical_lock->wait(); 93 } 94 } 95 96 void GC_locker::jni_lock(JavaThread* thread) { 97 assert(!thread->in_critical(), "shouldn't currently be in a critical region"); 98 MutexLocker mu(JNICritical_lock); 99 // Block entering threads if we know at least one thread is in a 100 // JNI critical region and we need a GC. 101 // We check that at least one thread is in a critical region before 102 // blocking because blocked threads are woken up by a thread exiting 103 // a JNI critical region. 104 while (is_active_and_needs_gc() || _doing_gc) { 105 JNICritical_lock->wait(); 106 } 107 thread->enter_critical(); 108 _jni_lock_count++; 109 increment_debug_jni_lock_count(); 110 } 111 112 void GC_locker::jni_unlock(JavaThread* thread) { 113 assert(thread->in_last_critical(), "should be exiting critical region"); 114 MutexLocker mu(JNICritical_lock); 115 _jni_lock_count--; 116 decrement_debug_jni_lock_count(); 117 thread->exit_critical(); 118 if (needs_gc() && !is_active_internal()) { 119 // We're the last thread out. Cause a GC to occur. 120 _doing_gc = true; 121 { 122 // Must give up the lock while at a safepoint 123 MutexUnlocker munlock(JNICritical_lock); 124 if (PrintJNIGCStalls && PrintGCDetails) { 125 ResourceMark rm; // JavaThread::name() allocates to convert to UTF8 126 gclog_or_tty->print_cr("%.3f: Thread \"%s\" is performing GC after exiting critical section, %d locked", 127 gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count); 128 } 129 Universe::heap()->collect(GCCause::_gc_locker); 130 } 131 _doing_gc = false; 132 _needs_gc = false; 133 JNICritical_lock->notify_all(); 134 } 135 } 136 137 // Implementation of No_GC_Verifier 138 139 #ifdef ASSERT 140 141 No_GC_Verifier::No_GC_Verifier(bool verifygc) { 142 _verifygc = verifygc; 143 if (_verifygc) { 144 CollectedHeap* h = Universe::heap(); 145 assert(!h->is_gc_active(), "GC active during No_GC_Verifier"); 146 _old_invocations = h->total_collections(); 147 } 148 } 149 150 151 No_GC_Verifier::~No_GC_Verifier() { 152 if (_verifygc) { 153 CollectedHeap* h = Universe::heap(); 154 assert(!h->is_gc_active(), "GC active during No_GC_Verifier"); 155 if (_old_invocations != h->total_collections()) { 156 fatal("collection in a No_GC_Verifier secured function"); 157 } 158 } 159 } 160 161 Pause_No_GC_Verifier::Pause_No_GC_Verifier(No_GC_Verifier * ngcv) { 162 _ngcv = ngcv; 163 if (_ngcv->_verifygc) { 164 // if we were verifying, then make sure that nothing is 165 // wrong before we "pause" verification 166 CollectedHeap* h = Universe::heap(); 167 assert(!h->is_gc_active(), "GC active during No_GC_Verifier"); 168 if (_ngcv->_old_invocations != h->total_collections()) { 169 fatal("collection in a No_GC_Verifier secured function"); 170 } 171 } 172 } 173 174 175 Pause_No_GC_Verifier::~Pause_No_GC_Verifier() { 176 if (_ngcv->_verifygc) { 177 // if we were verifying before, then reenable verification 178 CollectedHeap* h = Universe::heap(); 179 assert(!h->is_gc_active(), "GC active during No_GC_Verifier"); 180 _ngcv->_old_invocations = h->total_collections(); 181 } 182 } 183 184 185 // JRT_LEAF rules: 186 // A JRT_LEAF method may not interfere with safepointing by 187 // 1) acquiring or blocking on a Mutex or JavaLock - checked 188 // 2) allocating heap memory - checked 189 // 3) executing a VM operation - checked 190 // 4) executing a system call (including malloc) that could block or grab a lock 191 // 5) invoking GC 192 // 6) reaching a safepoint 193 // 7) running too long 194 // Nor may any method it calls. 195 JRT_Leaf_Verifier::JRT_Leaf_Verifier() 196 : No_Safepoint_Verifier(true, JRT_Leaf_Verifier::should_verify_GC()) 197 { 198 } 199 200 JRT_Leaf_Verifier::~JRT_Leaf_Verifier() 201 { 202 } 203 204 bool JRT_Leaf_Verifier::should_verify_GC() { 205 switch (JavaThread::current()->thread_state()) { 206 case _thread_in_Java: 207 // is in a leaf routine, there must be no safepoint. 208 return true; 209 case _thread_in_native: 210 // A native thread is not subject to safepoints. 211 // Even while it is in a leaf routine, GC is ok 212 return false; 213 default: 214 // Leaf routines cannot be called from other contexts. 215 ShouldNotReachHere(); 216 return false; 217 } 218 } 219 #endif