annotate src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp @ 3285:49a67202bc67

7011855: G1: non-product flag to artificially grow the heap Summary: It introduces non-product cmd line parameter G1DummyRegionsPerGC which indicates how many "dummy" regions to allocate at the end of each GC. This allows the G1 heap to grow artificially and makes concurrent marking cycles more frequent irrespective of what the application that is running is doing. The dummy regions will be found totally empty during cleanup so this parameter can also be used to stress the concurrent cleanup operation. Reviewed-by: brutisso, johnc
author tonyp
date Tue, 19 Apr 2011 15:46:59 -0400
parents a181f3a124dd
children 436b4a3231bf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1520
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1520
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1520
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1656
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1656
diff changeset
26 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1656
diff changeset
27 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1656
diff changeset
28 #include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1656
diff changeset
29 #include "gc_implementation/shared/isGCActiveMark.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1656
diff changeset
30 #include "memory/gcLocker.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1656
diff changeset
31 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1656
diff changeset
32 #include "utilities/dtrace.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
33 HS_DTRACE_PROBE_DECL(hs_private, cms__initmark__begin);
a61af66fc99e Initial load
duke
parents:
diff changeset
34 HS_DTRACE_PROBE_DECL(hs_private, cms__initmark__end);
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 HS_DTRACE_PROBE_DECL(hs_private, cms__remark__begin);
a61af66fc99e Initial load
duke
parents:
diff changeset
37 HS_DTRACE_PROBE_DECL(hs_private, cms__remark__end);
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 //////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // Methods in abstract class VM_CMS_Operation
a61af66fc99e Initial load
duke
parents:
diff changeset
41 //////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
42 void VM_CMS_Operation::acquire_pending_list_lock() {
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // The caller may block while communicating
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // with the SLT thread in order to acquire/release the PLL.
a61af66fc99e Initial load
duke
parents:
diff changeset
45 ConcurrentMarkSweepThread::slt()->
a61af66fc99e Initial load
duke
parents:
diff changeset
46 manipulatePLL(SurrogateLockerThread::acquirePLL);
a61af66fc99e Initial load
duke
parents:
diff changeset
47 }
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 void VM_CMS_Operation::release_and_notify_pending_list_lock() {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // The caller may block while communicating
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // with the SLT thread in order to acquire/release the PLL.
a61af66fc99e Initial load
duke
parents:
diff changeset
52 ConcurrentMarkSweepThread::slt()->
a61af66fc99e Initial load
duke
parents:
diff changeset
53 manipulatePLL(SurrogateLockerThread::releaseAndNotifyPLL);
a61af66fc99e Initial load
duke
parents:
diff changeset
54 }
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 void VM_CMS_Operation::verify_before_gc() {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 if (VerifyBeforeGC &&
a61af66fc99e Initial load
duke
parents:
diff changeset
58 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
59 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
60 FreelistLocker x(_collector);
a61af66fc99e Initial load
duke
parents:
diff changeset
61 MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
62 Universe::heap()->prepare_for_verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
63 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
64 }
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 void VM_CMS_Operation::verify_after_gc() {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 if (VerifyAfterGC &&
a61af66fc99e Initial load
duke
parents:
diff changeset
69 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
70 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 FreelistLocker x(_collector);
a61af66fc99e Initial load
duke
parents:
diff changeset
72 MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
73 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 bool VM_CMS_Operation::lost_race() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 if (CMSCollector::abstract_state() == CMSCollector::Idling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // We lost a race to a foreground collection
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // -- there's nothing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
81 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 }
a61af66fc99e Initial load
duke
parents:
diff changeset
83 assert(CMSCollector::abstract_state() == legal_state(),
a61af66fc99e Initial load
duke
parents:
diff changeset
84 "Inconsistent collector state?");
a61af66fc99e Initial load
duke
parents:
diff changeset
85 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 bool VM_CMS_Operation::doit_prologue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 assert(Thread::current()->is_ConcurrentGC_thread(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
90 assert(!CMSCollector::foregroundGCShouldWait(), "Possible deadlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
91 assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
92 "Possible deadlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 if (needs_pll()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 acquire_pending_list_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // Get the Heap_lock after the pending_list_lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
98 Heap_lock->lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
99 if (lost_race()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 assert(_prologue_succeeded == false, "Initialized in c'tor");
a61af66fc99e Initial load
duke
parents:
diff changeset
101 Heap_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
102 if (needs_pll()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 release_and_notify_pending_list_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
106 _prologue_succeeded = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108 return _prologue_succeeded;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 void VM_CMS_Operation::doit_epilogue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 assert(Thread::current()->is_ConcurrentGC_thread(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
113 assert(!CMSCollector::foregroundGCShouldWait(), "Possible deadlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
114 assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
115 "Possible deadlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // Release the Heap_lock first.
a61af66fc99e Initial load
duke
parents:
diff changeset
118 Heap_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
119 if (needs_pll()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 release_and_notify_pending_list_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123
a61af66fc99e Initial load
duke
parents:
diff changeset
124 //////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // Methods in class VM_CMS_Initial_Mark
a61af66fc99e Initial load
duke
parents:
diff changeset
126 //////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
127 void VM_CMS_Initial_Mark::doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
128 if (lost_race()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
130 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
132 HS_DTRACE_PROBE(hs_private, cms__initmark__begin);
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
135 GCCauseSetter gccs(gch, GCCause::_cms_initial_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
136
a61af66fc99e Initial load
duke
parents:
diff changeset
137 VM_CMS_Operation::verify_before_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 IsGCActiveMark x; // stop-world GC active
a61af66fc99e Initial load
duke
parents:
diff changeset
140 _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsInitial);
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 VM_CMS_Operation::verify_after_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
143 HS_DTRACE_PROBE(hs_private, cms__initmark__end);
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 //////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // Methods in class VM_CMS_Final_Remark_Operation
a61af66fc99e Initial load
duke
parents:
diff changeset
148 //////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
149 void VM_CMS_Final_Remark::doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 if (lost_race()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
152 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154 HS_DTRACE_PROBE(hs_private, cms__remark__begin);
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
157 GCCauseSetter gccs(gch, GCCause::_cms_final_remark);
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 VM_CMS_Operation::verify_before_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 IsGCActiveMark x; // stop-world GC active
a61af66fc99e Initial load
duke
parents:
diff changeset
162 _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsFinal);
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 VM_CMS_Operation::verify_after_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
165 HS_DTRACE_PROBE(hs_private, cms__remark__end);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // VM operation to invoke a concurrent collection of a
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // GenCollectedHeap heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
170 void VM_GenCollectFullConcurrent::doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 assert(Thread::current()->is_VM_thread(), "Should be VM thread");
1520
bb843ebc7c55 6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents: 0
diff changeset
172 assert(GCLockerInvokesConcurrent || ExplicitGCInvokesConcurrent, "Unexpected");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
175 if (_gc_count_before == gch->total_collections()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // The "full" of do_full_collection call below "forces"
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // a collection; the second arg, 0, below ensures that
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // only the young gen is collected. XXX In the future,
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // we'll probably need to have something in this interface
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // to say do this only if we are sure we will not bail
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // out to a full collection in this attempt, but that's
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // for the future.
a61af66fc99e Initial load
duke
parents:
diff changeset
183 assert(SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
184 "We can only be executing this arm of if at a safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
185 GCCauseSetter gccs(gch, _gc_cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 gch->do_full_collection(gch->must_clear_all_soft_refs(),
a61af66fc99e Initial load
duke
parents:
diff changeset
187 0 /* collect only youngest gen */);
a61af66fc99e Initial load
duke
parents:
diff changeset
188 } // Else no need for a foreground young gc
a61af66fc99e Initial load
duke
parents:
diff changeset
189 assert((_gc_count_before < gch->total_collections()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
190 (GC_locker::is_active() /* gc may have been skipped */
a61af66fc99e Initial load
duke
parents:
diff changeset
191 && (_gc_count_before == gch->total_collections())),
a61af66fc99e Initial load
duke
parents:
diff changeset
192 "total_collections() should be monotonically increasing");
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
195 assert(_full_gc_count_before <= gch->total_full_collections(), "Error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
196 if (gch->total_full_collections() == _full_gc_count_before) {
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
197 // Disable iCMS until the full collection is done, and
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
198 // remember that we did so.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
199 CMSCollector::disable_icms();
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
200 _disabled_icms = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // In case CMS thread was in icms_wait(), wake it up.
a61af66fc99e Initial load
duke
parents:
diff changeset
202 CMSCollector::start_icms();
1520
bb843ebc7c55 6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents: 0
diff changeset
203 // Nudge the CMS thread to start a concurrent collection.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
204 CMSCollector::request_full_gc(_full_gc_count_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 } else {
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
206 assert(_full_gc_count_before < gch->total_full_collections(), "Error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
207 FullGCCount_lock->notify_all(); // Inform the Java thread its work is done
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 bool VM_GenCollectFullConcurrent::evaluate_at_safepoint() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 Thread* thr = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
213 assert(thr != NULL, "Unexpected tid");
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if (!thr->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 assert(thr->is_VM_thread(), "Expected to be evaluated by VM thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
216 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if (_gc_count_before != gch->total_collections()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // No need to do a young gc, we'll just nudge the CMS thread
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // in the doit() method above, to be executed soon.
a61af66fc99e Initial load
duke
parents:
diff changeset
220 assert(_gc_count_before < gch->total_collections(),
a61af66fc99e Initial load
duke
parents:
diff changeset
221 "total_collections() should be monotnically increasing");
a61af66fc99e Initial load
duke
parents:
diff changeset
222 return false; // no need for foreground young gc
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225 return true; // may still need foreground young gc
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 void VM_GenCollectFullConcurrent::doit_epilogue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 Thread* thr = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
231 assert(thr->is_Java_thread(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
232 JavaThread* jt = (JavaThread*)thr;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // Release the Heap_lock first.
a61af66fc99e Initial load
duke
parents:
diff changeset
234 Heap_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
235 release_and_notify_pending_list_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // It is fine to test whether completed collections has
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // exceeded our request count without locking because
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // the completion count is monotonically increasing;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // this will break for very long-running apps when the
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // count overflows and wraps around. XXX fix me !!!
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // e.g. at the rate of 1 full gc per ms, this could
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // overflow in about 1000 years.
a61af66fc99e Initial load
duke
parents:
diff changeset
244 GenCollectedHeap* gch = GenCollectedHeap::heap();
1520
bb843ebc7c55 6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents: 0
diff changeset
245 if (_gc_cause != GCCause::_gc_locker &&
bb843ebc7c55 6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents: 0
diff changeset
246 gch->total_full_collections_completed() <= _full_gc_count_before) {
1656
4e5661ba9d98 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 1552
diff changeset
247 // maybe we should change the condition to test _gc_cause ==
4e5661ba9d98 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 1552
diff changeset
248 // GCCause::_java_lang_system_gc, instead of
4e5661ba9d98 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 1552
diff changeset
249 // _gc_cause != GCCause::_gc_locker
4e5661ba9d98 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 1552
diff changeset
250 assert(_gc_cause == GCCause::_java_lang_system_gc,
4e5661ba9d98 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 1552
diff changeset
251 "the only way to get here if this was a System.gc()-induced GC");
1520
bb843ebc7c55 6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents: 0
diff changeset
252 assert(ExplicitGCInvokesConcurrent, "Error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // Now, wait for witnessing concurrent gc cycle to complete,
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // but do so in native mode, because we want to lock the
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // FullGCEvent_lock, which may be needed by the VM thread
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // or by the CMS thread, so we do not want to be suspended
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // while holding that lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
258 ThreadToNativeFromVM native(jt);
a61af66fc99e Initial load
duke
parents:
diff changeset
259 MutexLockerEx ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // Either a concurrent or a stop-world full gc is sufficient
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // witness to our request.
a61af66fc99e Initial load
duke
parents:
diff changeset
262 while (gch->total_full_collections_completed() <= _full_gc_count_before) {
a61af66fc99e Initial load
duke
parents:
diff changeset
263 FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
265 }
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
266 // Enable iCMS back if we disabled it earlier.
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
267 if (_disabled_icms) {
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
268 CMSCollector::enable_icms();
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 1972
diff changeset
269 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
270 }