118 JNICritical_lock->wait();
119 }
120 thread->enter_critical();
121 _jni_lock_count++;
122 increment_debug_jni_lock_count();
123 }
124
125 void GCLocker::jni_unlock(JavaThread* thread) {
126 assert(thread->in_last_critical(), "should be exiting critical region");
127 MutexLocker mu(JNICritical_lock);
128 _jni_lock_count--;
129 decrement_debug_jni_lock_count();
130 thread->exit_critical();
131 if (needs_gc() && !is_active_internal()) {
132 // We're the last thread out. Cause a GC to occur.
133 _doing_gc = true;
134 {
135 // Must give up the lock while at a safepoint
136 MutexUnlocker munlock(JNICritical_lock);
137 log_debug_jni("Performing GC after exiting critical section.");
138 Universe::heap()->collect(GCCause::_gc_locker);
139 }
140 _doing_gc = false;
141 _needs_gc = false;
142 JNICritical_lock->notify_all();
143 }
144 }
145
146 // Implementation of NoGCVerifier
147
148 #ifdef ASSERT
149
150 NoGCVerifier::NoGCVerifier(bool verifygc) {
151 _verifygc = verifygc;
152 if (_verifygc) {
153 CollectedHeap* h = Universe::heap();
154 assert(!h->is_gc_active(), "GC active during NoGCVerifier");
155 _old_invocations = h->total_collections();
156 }
157 }
158
159
160 NoGCVerifier::~NoGCVerifier() {
161 if (_verifygc) {
162 CollectedHeap* h = Universe::heap();
163 assert(!h->is_gc_active(), "GC active during NoGCVerifier");
164 if (_old_invocations != h->total_collections()) {
165 fatal("collection in a NoGCVerifier secured function");
166 }
167 }
168 }
169
170 PauseNoGCVerifier::PauseNoGCVerifier(NoGCVerifier * ngcv) {
171 _ngcv = ngcv;
172 if (_ngcv->_verifygc) {
173 // if we were verifying, then make sure that nothing is
174 // wrong before we "pause" verification
175 CollectedHeap* h = Universe::heap();
176 assert(!h->is_gc_active(), "GC active during NoGCVerifier");
177 if (_ngcv->_old_invocations != h->total_collections()) {
178 fatal("collection in a NoGCVerifier secured function");
179 }
180 }
181 }
182
183
184 PauseNoGCVerifier::~PauseNoGCVerifier() {
185 if (_ngcv->_verifygc) {
186 // if we were verifying before, then reenable verification
187 CollectedHeap* h = Universe::heap();
188 assert(!h->is_gc_active(), "GC active during NoGCVerifier");
189 _ngcv->_old_invocations = h->total_collections();
190 }
191 }
192
193
194 // JRT_LEAF rules:
195 // A JRT_LEAF method may not interfere with safepointing by
196 // 1) acquiring or blocking on a Mutex or JavaLock - checked
197 // 2) allocating heap memory - checked
198 // 3) executing a VM operation - checked
199 // 4) executing a system call (including malloc) that could block or grab a lock
200 // 5) invoking GC
201 // 6) reaching a safepoint
202 // 7) running too long
203 // Nor may any method it calls.
204 JRTLeafVerifier::JRTLeafVerifier()
205 : NoSafepointVerifier(true, JRTLeafVerifier::should_verify_GC())
206 {
207 }
|
118 JNICritical_lock->wait();
119 }
120 thread->enter_critical();
121 _jni_lock_count++;
122 increment_debug_jni_lock_count();
123 }
124
125 void GCLocker::jni_unlock(JavaThread* thread) {
126 assert(thread->in_last_critical(), "should be exiting critical region");
127 MutexLocker mu(JNICritical_lock);
128 _jni_lock_count--;
129 decrement_debug_jni_lock_count();
130 thread->exit_critical();
131 if (needs_gc() && !is_active_internal()) {
132 // We're the last thread out. Cause a GC to occur.
133 _doing_gc = true;
134 {
135 // Must give up the lock while at a safepoint
136 MutexUnlocker munlock(JNICritical_lock);
137 log_debug_jni("Performing GC after exiting critical section.");
138 GC::gc()->heap()->collect(GCCause::_gc_locker);
139 }
140 _doing_gc = false;
141 _needs_gc = false;
142 JNICritical_lock->notify_all();
143 }
144 }
145
146 // Implementation of NoGCVerifier
147
148 #ifdef ASSERT
149
150 NoGCVerifier::NoGCVerifier(bool verifygc) {
151 _verifygc = verifygc;
152 if (_verifygc) {
153 CollectedHeap* h = GC::gc()->heap();
154 assert(!h->is_gc_active(), "GC active during NoGCVerifier");
155 _old_invocations = h->total_collections();
156 }
157 }
158
159
160 NoGCVerifier::~NoGCVerifier() {
161 if (_verifygc) {
162 CollectedHeap* h = GC::gc()->heap();
163 assert(!h->is_gc_active(), "GC active during NoGCVerifier");
164 if (_old_invocations != h->total_collections()) {
165 fatal("collection in a NoGCVerifier secured function");
166 }
167 }
168 }
169
170 PauseNoGCVerifier::PauseNoGCVerifier(NoGCVerifier * ngcv) {
171 _ngcv = ngcv;
172 if (_ngcv->_verifygc) {
173 // if we were verifying, then make sure that nothing is
174 // wrong before we "pause" verification
175 CollectedHeap* h = GC::gc()->heap();
176 assert(!h->is_gc_active(), "GC active during NoGCVerifier");
177 if (_ngcv->_old_invocations != h->total_collections()) {
178 fatal("collection in a NoGCVerifier secured function");
179 }
180 }
181 }
182
183
184 PauseNoGCVerifier::~PauseNoGCVerifier() {
185 if (_ngcv->_verifygc) {
186 // if we were verifying before, then reenable verification
187 CollectedHeap* h = GC::gc()->heap();
188 assert(!h->is_gc_active(), "GC active during NoGCVerifier");
189 _ngcv->_old_invocations = h->total_collections();
190 }
191 }
192
193
194 // JRT_LEAF rules:
195 // A JRT_LEAF method may not interfere with safepointing by
196 // 1) acquiring or blocking on a Mutex or JavaLock - checked
197 // 2) allocating heap memory - checked
198 // 3) executing a VM operation - checked
199 // 4) executing a system call (including malloc) that could block or grab a lock
200 // 5) invoking GC
201 // 6) reaching a safepoint
202 // 7) running too long
203 // Nor may any method it calls.
204 JRTLeafVerifier::JRTLeafVerifier()
205 : NoSafepointVerifier(true, JRTLeafVerifier::should_verify_GC())
206 {
207 }
|