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 "gc/cms/concurrentMarkSweepGeneration.inline.hpp"
27 #include "gc/cms/concurrentMarkSweepThread.hpp"
28 #include "gc/cms/vmCMSOperations.hpp"
29 #include "gc/shared/gcLocker.inline.hpp"
30 #include "gc/shared/gcTimer.hpp"
31 #include "gc/shared/gcTraceTime.inline.hpp"
32 #include "gc/shared/isGCActiveMark.hpp"
33 #include "runtime/interfaceSupport.hpp"
34 #include "runtime/os.hpp"
35 #include "utilities/dtrace.hpp"
36
37 //////////////////////////////////////////////////////////
38 // Methods in abstract class VM_CMS_Operation
39 //////////////////////////////////////////////////////////
40 void VM_CMS_Operation::acquire_pending_list_lock() {
41 _pending_list_locker.lock();
42 }
43
44 void VM_CMS_Operation::release_and_notify_pending_list_lock() {
45 _pending_list_locker.unlock();
46 }
47
48 void VM_CMS_Operation::verify_before_gc() {
49 if (VerifyBeforeGC &&
50 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
51 GCTraceTime(Info, gc, phases, verify) tm("Verify Before", _collector->_gc_timer_cm);
52 HandleMark hm;
53 FreelistLocker x(_collector);
54 MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
55 GenCollectedHeap::heap()->prepare_for_verify();
56 Universe::verify();
57 }
58 }
59
60 void VM_CMS_Operation::verify_after_gc() {
61 if (VerifyAfterGC &&
62 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
63 GCTraceTime(Info, gc, phases, verify) tm("Verify After", _collector->_gc_timer_cm);
64 HandleMark hm;
65 FreelistLocker x(_collector);
66 MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
67 Universe::verify();
68 }
69 }
70
71 bool VM_CMS_Operation::lost_race() const {
72 if (CMSCollector::abstract_state() == CMSCollector::Idling) {
73 // We lost a race to a foreground collection
74 // -- there's nothing to do
75 return true;
76 }
77 assert(CMSCollector::abstract_state() == legal_state(),
78 "Inconsistent collector state?");
79 return false;
80 }
81
82 bool VM_CMS_Operation::doit_prologue() {
83 assert(Thread::current()->is_ConcurrentGC_thread(), "just checking");
84 assert(!CMSCollector::foregroundGCShouldWait(), "Possible deadlock");
85 assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
86 "Possible deadlock");
87
88 if (needs_pending_list_lock()) {
89 acquire_pending_list_lock();
90 }
91 // Get the Heap_lock after the pending_list_lock.
92 Heap_lock->lock();
93 if (lost_race()) {
94 assert(_prologue_succeeded == false, "Initialized in c'tor");
95 Heap_lock->unlock();
96 if (needs_pending_list_lock()) {
97 release_and_notify_pending_list_lock();
98 }
99 } else {
100 _prologue_succeeded = true;
101 }
102 return _prologue_succeeded;
103 }
104
105 void VM_CMS_Operation::doit_epilogue() {
106 assert(Thread::current()->is_ConcurrentGC_thread(), "just checking");
107 assert(!CMSCollector::foregroundGCShouldWait(), "Possible deadlock");
108 assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
109 "Possible deadlock");
110
111 // Release the Heap_lock first.
112 Heap_lock->unlock();
113 if (needs_pending_list_lock()) {
114 release_and_notify_pending_list_lock();
115 }
116 }
117
118 //////////////////////////////////////////////////////////
119 // Methods in class VM_CMS_Initial_Mark
120 //////////////////////////////////////////////////////////
121 void VM_CMS_Initial_Mark::doit() {
122 if (lost_race()) {
123 // Nothing to do.
124 return;
125 }
126 HS_PRIVATE_CMS_INITMARK_BEGIN();
127 GCIdMark gc_id_mark(_gc_id);
128
129 _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark");
130
131 GenCollectedHeap* gch = GenCollectedHeap::heap();
132 GCCauseSetter gccs(gch, GCCause::_cms_initial_mark);
133
134 VM_CMS_Operation::verify_before_gc();
135
213 assert(thr != NULL, "Unexpected tid");
214 if (!thr->is_Java_thread()) {
215 assert(thr->is_VM_thread(), "Expected to be evaluated by VM thread");
216 GenCollectedHeap* gch = GenCollectedHeap::heap();
217 if (_gc_count_before != gch->total_collections()) {
218 // No need to do a young gc, we'll just nudge the CMS thread
219 // in the doit() method above, to be executed soon.
220 assert(_gc_count_before < gch->total_collections(),
221 "total_collections() should be monotonically increasing");
222 return false; // no need for foreground young gc
223 }
224 }
225 return true; // may still need foreground young gc
226 }
227
228
229 void VM_GenCollectFullConcurrent::doit_epilogue() {
230 Thread* thr = Thread::current();
231 assert(thr->is_Java_thread(), "just checking");
232 JavaThread* jt = (JavaThread*)thr;
233 // Release the Heap_lock first.
234 Heap_lock->unlock();
235 release_and_notify_pending_list_lock();
236
237 // It is fine to test whether completed collections has
238 // exceeded our request count without locking because
239 // the completion count is monotonically increasing;
240 // this will break for very long-running apps when the
241 // count overflows and wraps around. XXX fix me !!!
242 // e.g. at the rate of 1 full gc per ms, this could
243 // overflow in about 1000 years.
244 GenCollectedHeap* gch = GenCollectedHeap::heap();
245 if (_gc_cause != GCCause::_gc_locker &&
246 gch->total_full_collections_completed() <= _full_gc_count_before) {
247 // maybe we should change the condition to test _gc_cause ==
248 // GCCause::_java_lang_system_gc or GCCause::_dcmd_gc_run,
249 // instead of _gc_cause != GCCause::_gc_locker
250 assert(GCCause::is_user_requested_gc(_gc_cause),
251 "the only way to get here if this was a System.gc()-induced GC");
252 assert(ExplicitGCInvokesConcurrent, "Error");
253 // Now, wait for witnessing concurrent gc cycle to complete,
254 // but do so in native mode, because we want to lock the
255 // FullGCEvent_lock, which may be needed by the VM thread
|
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 "gc/cms/concurrentMarkSweepGeneration.inline.hpp"
27 #include "gc/cms/concurrentMarkSweepThread.hpp"
28 #include "gc/cms/vmCMSOperations.hpp"
29 #include "gc/shared/gcLocker.inline.hpp"
30 #include "gc/shared/gcTimer.hpp"
31 #include "gc/shared/gcTraceTime.inline.hpp"
32 #include "gc/shared/isGCActiveMark.hpp"
33 #include "runtime/interfaceSupport.hpp"
34 #include "runtime/os.hpp"
35 #include "utilities/dtrace.hpp"
36
37 //////////////////////////////////////////////////////////
38 // Methods in abstract class VM_CMS_Operation
39 //////////////////////////////////////////////////////////
40 void VM_CMS_Operation::verify_before_gc() {
41 if (VerifyBeforeGC &&
42 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
43 GCTraceTime(Info, gc, phases, verify) tm("Verify Before", _collector->_gc_timer_cm);
44 HandleMark hm;
45 FreelistLocker x(_collector);
46 MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
47 GenCollectedHeap::heap()->prepare_for_verify();
48 Universe::verify();
49 }
50 }
51
52 void VM_CMS_Operation::verify_after_gc() {
53 if (VerifyAfterGC &&
54 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
55 GCTraceTime(Info, gc, phases, verify) tm("Verify After", _collector->_gc_timer_cm);
56 HandleMark hm;
57 FreelistLocker x(_collector);
58 MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
59 Universe::verify();
60 }
61 }
62
63 bool VM_CMS_Operation::lost_race() const {
64 if (CMSCollector::abstract_state() == CMSCollector::Idling) {
65 // We lost a race to a foreground collection
66 // -- there's nothing to do
67 return true;
68 }
69 assert(CMSCollector::abstract_state() == legal_state(),
70 "Inconsistent collector state?");
71 return false;
72 }
73
74 bool VM_CMS_Operation::doit_prologue() {
75 assert(Thread::current()->is_ConcurrentGC_thread(), "just checking");
76 assert(!CMSCollector::foregroundGCShouldWait(), "Possible deadlock");
77 assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
78 "Possible deadlock");
79
80 Heap_lock->lock();
81 if (lost_race()) {
82 assert(_prologue_succeeded == false, "Initialized in c'tor");
83 Heap_lock->unlock();
84 } else {
85 _prologue_succeeded = true;
86 }
87 return _prologue_succeeded;
88 }
89
90 void VM_CMS_Operation::doit_epilogue() {
91 assert(Thread::current()->is_ConcurrentGC_thread(), "just checking");
92 assert(!CMSCollector::foregroundGCShouldWait(), "Possible deadlock");
93 assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
94 "Possible deadlock");
95
96 if (Universe::has_reference_pending_list()) {
97 Heap_lock->notify_all();
98 }
99 Heap_lock->unlock();
100 }
101
102 //////////////////////////////////////////////////////////
103 // Methods in class VM_CMS_Initial_Mark
104 //////////////////////////////////////////////////////////
105 void VM_CMS_Initial_Mark::doit() {
106 if (lost_race()) {
107 // Nothing to do.
108 return;
109 }
110 HS_PRIVATE_CMS_INITMARK_BEGIN();
111 GCIdMark gc_id_mark(_gc_id);
112
113 _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark");
114
115 GenCollectedHeap* gch = GenCollectedHeap::heap();
116 GCCauseSetter gccs(gch, GCCause::_cms_initial_mark);
117
118 VM_CMS_Operation::verify_before_gc();
119
197 assert(thr != NULL, "Unexpected tid");
198 if (!thr->is_Java_thread()) {
199 assert(thr->is_VM_thread(), "Expected to be evaluated by VM thread");
200 GenCollectedHeap* gch = GenCollectedHeap::heap();
201 if (_gc_count_before != gch->total_collections()) {
202 // No need to do a young gc, we'll just nudge the CMS thread
203 // in the doit() method above, to be executed soon.
204 assert(_gc_count_before < gch->total_collections(),
205 "total_collections() should be monotonically increasing");
206 return false; // no need for foreground young gc
207 }
208 }
209 return true; // may still need foreground young gc
210 }
211
212
213 void VM_GenCollectFullConcurrent::doit_epilogue() {
214 Thread* thr = Thread::current();
215 assert(thr->is_Java_thread(), "just checking");
216 JavaThread* jt = (JavaThread*)thr;
217
218 if (Universe::has_reference_pending_list()) {
219 Heap_lock->notify_all();
220 }
221 Heap_lock->unlock();
222
223 // It is fine to test whether completed collections has
224 // exceeded our request count without locking because
225 // the completion count is monotonically increasing;
226 // this will break for very long-running apps when the
227 // count overflows and wraps around. XXX fix me !!!
228 // e.g. at the rate of 1 full gc per ms, this could
229 // overflow in about 1000 years.
230 GenCollectedHeap* gch = GenCollectedHeap::heap();
231 if (_gc_cause != GCCause::_gc_locker &&
232 gch->total_full_collections_completed() <= _full_gc_count_before) {
233 // maybe we should change the condition to test _gc_cause ==
234 // GCCause::_java_lang_system_gc or GCCause::_dcmd_gc_run,
235 // instead of _gc_cause != GCCause::_gc_locker
236 assert(GCCause::is_user_requested_gc(_gc_cause),
237 "the only way to get here if this was a System.gc()-induced GC");
238 assert(ExplicitGCInvokesConcurrent, "Error");
239 // Now, wait for witnessing concurrent gc cycle to complete,
240 // but do so in native mode, because we want to lock the
241 // FullGCEvent_lock, which may be needed by the VM thread
|