equal
deleted
inserted
replaced
34 #include "runtime/threadSMR.hpp" |
34 #include "runtime/threadSMR.hpp" |
35 |
35 |
36 volatile jint GCLocker::_jni_lock_count = 0; |
36 volatile jint GCLocker::_jni_lock_count = 0; |
37 volatile bool GCLocker::_needs_gc = false; |
37 volatile bool GCLocker::_needs_gc = false; |
38 volatile bool GCLocker::_doing_gc = false; |
38 volatile bool GCLocker::_doing_gc = false; |
|
39 unsigned int GCLocker::_total_collections = 0; |
39 |
40 |
40 #ifdef ASSERT |
41 #ifdef ASSERT |
41 volatile jint GCLocker::_debug_jni_lock_count = 0; |
42 volatile jint GCLocker::_debug_jni_lock_count = 0; |
42 #endif |
43 #endif |
43 |
44 |
113 while (needs_gc()) { |
114 while (needs_gc()) { |
114 ml.wait(); |
115 ml.wait(); |
115 } |
116 } |
116 } |
117 } |
117 |
118 |
|
119 bool GCLocker::should_discard(GCCause::Cause cause, uint total_collections) { |
|
120 return (cause == GCCause::_gc_locker) && |
|
121 (_total_collections != total_collections); |
|
122 } |
|
123 |
118 void GCLocker::jni_lock(JavaThread* thread) { |
124 void GCLocker::jni_lock(JavaThread* thread) { |
119 assert(!thread->in_critical(), "shouldn't currently be in a critical region"); |
125 assert(!thread->in_critical(), "shouldn't currently be in a critical region"); |
120 MonitorLocker ml(JNICritical_lock); |
126 MonitorLocker ml(JNICritical_lock); |
121 // Block entering threads if we know at least one thread is in a |
127 // Block entering threads if we know at least one thread is in a |
122 // JNI critical region and we need a GC. |
128 // JNI critical region and we need a GC. |
136 MutexLocker mu(JNICritical_lock); |
142 MutexLocker mu(JNICritical_lock); |
137 _jni_lock_count--; |
143 _jni_lock_count--; |
138 decrement_debug_jni_lock_count(); |
144 decrement_debug_jni_lock_count(); |
139 thread->exit_critical(); |
145 thread->exit_critical(); |
140 if (needs_gc() && !is_active_internal()) { |
146 if (needs_gc() && !is_active_internal()) { |
141 // We're the last thread out. Cause a GC to occur. |
147 // We're the last thread out. Request a GC. |
|
148 // Capture the current total collections, to allow detection of |
|
149 // other collections that make this one unnecessary. The value of |
|
150 // total_collections() is only changed at a safepoint, so there |
|
151 // must not be a safepoint between the lock becoming inactive and |
|
152 // getting the count, else there may be unnecessary GCLocker GCs. |
|
153 _total_collections = Universe::heap()->total_collections(); |
142 _doing_gc = true; |
154 _doing_gc = true; |
143 { |
155 { |
144 // Must give up the lock while at a safepoint |
156 // Must give up the lock while at a safepoint |
145 MutexUnlocker munlock(JNICritical_lock); |
157 MutexUnlocker munlock(JNICritical_lock); |
146 log_debug_jni("Performing GC after exiting critical section."); |
158 log_debug_jni("Performing GC after exiting critical section."); |