Mercurial > hg > truffle
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 |
rev | line source |
---|---|
0 | 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 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
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 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp" | |
27 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" | |
28 #include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp" | |
29 #include "gc_implementation/shared/isGCActiveMark.hpp" | |
30 #include "memory/gcLocker.inline.hpp" | |
31 #include "runtime/interfaceSupport.hpp" | |
32 #include "utilities/dtrace.hpp" | |
0 | 33 HS_DTRACE_PROBE_DECL(hs_private, cms__initmark__begin); |
34 HS_DTRACE_PROBE_DECL(hs_private, cms__initmark__end); | |
35 | |
36 HS_DTRACE_PROBE_DECL(hs_private, cms__remark__begin); | |
37 HS_DTRACE_PROBE_DECL(hs_private, cms__remark__end); | |
38 | |
39 ////////////////////////////////////////////////////////// | |
40 // Methods in abstract class VM_CMS_Operation | |
41 ////////////////////////////////////////////////////////// | |
42 void VM_CMS_Operation::acquire_pending_list_lock() { | |
43 // The caller may block while communicating | |
44 // with the SLT thread in order to acquire/release the PLL. | |
45 ConcurrentMarkSweepThread::slt()-> | |
46 manipulatePLL(SurrogateLockerThread::acquirePLL); | |
47 } | |
48 | |
49 void VM_CMS_Operation::release_and_notify_pending_list_lock() { | |
50 // The caller may block while communicating | |
51 // with the SLT thread in order to acquire/release the PLL. | |
52 ConcurrentMarkSweepThread::slt()-> | |
53 manipulatePLL(SurrogateLockerThread::releaseAndNotifyPLL); | |
54 } | |
55 | |
56 void VM_CMS_Operation::verify_before_gc() { | |
57 if (VerifyBeforeGC && | |
58 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) { | |
59 HandleMark hm; | |
60 FreelistLocker x(_collector); | |
61 MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag); | |
62 Universe::heap()->prepare_for_verify(); | |
63 Universe::verify(true); | |
64 } | |
65 } | |
66 | |
67 void VM_CMS_Operation::verify_after_gc() { | |
68 if (VerifyAfterGC && | |
69 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) { | |
70 HandleMark hm; | |
71 FreelistLocker x(_collector); | |
72 MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag); | |
73 Universe::verify(true); | |
74 } | |
75 } | |
76 | |
77 bool VM_CMS_Operation::lost_race() const { | |
78 if (CMSCollector::abstract_state() == CMSCollector::Idling) { | |
79 // We lost a race to a foreground collection | |
80 // -- there's nothing to do | |
81 return true; | |
82 } | |
83 assert(CMSCollector::abstract_state() == legal_state(), | |
84 "Inconsistent collector state?"); | |
85 return false; | |
86 } | |
87 | |
88 bool VM_CMS_Operation::doit_prologue() { | |
89 assert(Thread::current()->is_ConcurrentGC_thread(), "just checking"); | |
90 assert(!CMSCollector::foregroundGCShouldWait(), "Possible deadlock"); | |
91 assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(), | |
92 "Possible deadlock"); | |
93 | |
94 if (needs_pll()) { | |
95 acquire_pending_list_lock(); | |
96 } | |
97 // Get the Heap_lock after the pending_list_lock. | |
98 Heap_lock->lock(); | |
99 if (lost_race()) { | |
100 assert(_prologue_succeeded == false, "Initialized in c'tor"); | |
101 Heap_lock->unlock(); | |
102 if (needs_pll()) { | |
103 release_and_notify_pending_list_lock(); | |
104 } | |
105 } else { | |
106 _prologue_succeeded = true; | |
107 } | |
108 return _prologue_succeeded; | |
109 } | |
110 | |
111 void VM_CMS_Operation::doit_epilogue() { | |
112 assert(Thread::current()->is_ConcurrentGC_thread(), "just checking"); | |
113 assert(!CMSCollector::foregroundGCShouldWait(), "Possible deadlock"); | |
114 assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(), | |
115 "Possible deadlock"); | |
116 | |
117 // Release the Heap_lock first. | |
118 Heap_lock->unlock(); | |
119 if (needs_pll()) { | |
120 release_and_notify_pending_list_lock(); | |
121 } | |
122 } | |
123 | |
124 ////////////////////////////////////////////////////////// | |
125 // Methods in class VM_CMS_Initial_Mark | |
126 ////////////////////////////////////////////////////////// | |
127 void VM_CMS_Initial_Mark::doit() { | |
128 if (lost_race()) { | |
129 // Nothing to do. | |
130 return; | |
131 } | |
132 HS_DTRACE_PROBE(hs_private, cms__initmark__begin); | |
133 | |
134 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
135 GCCauseSetter gccs(gch, GCCause::_cms_initial_mark); | |
136 | |
137 VM_CMS_Operation::verify_before_gc(); | |
138 | |
139 IsGCActiveMark x; // stop-world GC active | |
140 _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsInitial); | |
141 | |
142 VM_CMS_Operation::verify_after_gc(); | |
143 HS_DTRACE_PROBE(hs_private, cms__initmark__end); | |
144 } | |
145 | |
146 ////////////////////////////////////////////////////////// | |
147 // Methods in class VM_CMS_Final_Remark_Operation | |
148 ////////////////////////////////////////////////////////// | |
149 void VM_CMS_Final_Remark::doit() { | |
150 if (lost_race()) { | |
151 // Nothing to do. | |
152 return; | |
153 } | |
154 HS_DTRACE_PROBE(hs_private, cms__remark__begin); | |
155 | |
156 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
157 GCCauseSetter gccs(gch, GCCause::_cms_final_remark); | |
158 | |
159 VM_CMS_Operation::verify_before_gc(); | |
160 | |
161 IsGCActiveMark x; // stop-world GC active | |
162 _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsFinal); | |
163 | |
164 VM_CMS_Operation::verify_after_gc(); | |
165 HS_DTRACE_PROBE(hs_private, cms__remark__end); | |
166 } | |
167 | |
168 // VM operation to invoke a concurrent collection of a | |
169 // GenCollectedHeap heap. | |
170 void VM_GenCollectFullConcurrent::doit() { | |
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 | 173 |
174 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
175 if (_gc_count_before == gch->total_collections()) { | |
176 // The "full" of do_full_collection call below "forces" | |
177 // a collection; the second arg, 0, below ensures that | |
178 // only the young gen is collected. XXX In the future, | |
179 // we'll probably need to have something in this interface | |
180 // to say do this only if we are sure we will not bail | |
181 // out to a full collection in this attempt, but that's | |
182 // for the future. | |
183 assert(SafepointSynchronize::is_at_safepoint(), | |
184 "We can only be executing this arm of if at a safepoint"); | |
185 GCCauseSetter gccs(gch, _gc_cause); | |
186 gch->do_full_collection(gch->must_clear_all_soft_refs(), | |
187 0 /* collect only youngest gen */); | |
188 } // Else no need for a foreground young gc | |
189 assert((_gc_count_before < gch->total_collections()) || | |
190 (GC_locker::is_active() /* gc may have been skipped */ | |
191 && (_gc_count_before == gch->total_collections())), | |
192 "total_collections() should be monotonically increasing"); | |
193 | |
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 | 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 | 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 | 201 // In case CMS thread was in icms_wait(), wake it up. |
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 | 204 CMSCollector::request_full_gc(_full_gc_count_before); |
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 | 207 FullGCCount_lock->notify_all(); // Inform the Java thread its work is done |
208 } | |
209 } | |
210 | |
211 bool VM_GenCollectFullConcurrent::evaluate_at_safepoint() const { | |
212 Thread* thr = Thread::current(); | |
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 monotnically 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(); | |
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 | 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 | |
256 // or by the CMS thread, so we do not want to be suspended | |
257 // while holding that lock. | |
258 ThreadToNativeFromVM native(jt); | |
259 MutexLockerEx ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag); | |
260 // Either a concurrent or a stop-world full gc is sufficient | |
261 // witness to our request. | |
262 while (gch->total_full_collections_completed() <= _full_gc_count_before) { | |
263 FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag); | |
264 } | |
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 | 270 } |