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