annotate src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.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 b099aaf51bf8
children 1f4413413144
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: 2226
diff changeset
2 * Copyright (c) 2001, 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: 1521
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1521
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: 1521
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: 1888
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
26 #include "classfile/symbolTable.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
27 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
28 #include "code/codeCache.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
29 #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
30 #include "gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
31 #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
32 #include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
33 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
34 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
35 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
36 #include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
37 #include "gc_implementation/parNew/parNewGeneration.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
38 #include "gc_implementation/shared/collectorCounters.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
39 #include "gc_implementation/shared/isGCActiveMark.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
40 #include "gc_interface/collectedHeap.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
41 #include "memory/cardTableRS.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
42 #include "memory/collectorPolicy.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
43 #include "memory/gcLocker.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
44 #include "memory/genCollectedHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
45 #include "memory/genMarkSweep.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
46 #include "memory/genOopClosures.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
47 #include "memory/iterator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
48 #include "memory/referencePolicy.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
49 #include "memory/resourceArea.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
50 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
51 #include "prims/jvmtiExport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
52 #include "runtime/globals_extension.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
53 #include "runtime/handles.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
54 #include "runtime/java.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
55 #include "runtime/vmThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
56 #include "services/memoryService.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1888
diff changeset
57 #include "services/runtimeService.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // statics
a61af66fc99e Initial load
duke
parents:
diff changeset
60 CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 bool CMSCollector::_full_gc_requested = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 //////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // In support of CMS/VM thread synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
65 //////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // We split use of the CGC_lock into 2 "levels".
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // The low-level locking is of the usual CGC_lock monitor. We introduce
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // a higher level "token" (hereafter "CMS token") built on top of the
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // low level monitor (hereafter "CGC lock").
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // The token-passing protocol gives priority to the VM thread. The
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // CMS-lock doesn't provide any fairness guarantees, but clients
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // should ensure that it is only held for very short, bounded
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // durations.
a61af66fc99e Initial load
duke
parents:
diff changeset
74 //
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // When either of the CMS thread or the VM thread is involved in
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // collection operations during which it does not want the other
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // thread to interfere, it obtains the CMS token.
a61af66fc99e Initial load
duke
parents:
diff changeset
78 //
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // If either thread tries to get the token while the other has
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // it, that thread waits. However, if the VM thread and CMS thread
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // both want the token, then the VM thread gets priority while the
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // CMS thread waits. This ensures, for instance, that the "concurrent"
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // phases of the CMS thread's work do not block out the VM thread
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // for long periods of time as the CMS thread continues to hog
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // the token. (See bug 4616232).
a61af66fc99e Initial load
duke
parents:
diff changeset
86 //
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // The baton-passing functions are, however, controlled by the
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // flags _foregroundGCShouldWait and _foregroundGCIsActive,
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // and here the low-level CMS lock, not the high level token,
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // ensures mutual exclusion.
a61af66fc99e Initial load
duke
parents:
diff changeset
91 //
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // Two important conditions that we have to satisfy:
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // 1. if a thread does a low-level wait on the CMS lock, then it
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // relinquishes the CMS token if it were holding that token
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // when it acquired the low-level CMS lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // 2. any low-level notifications on the low-level lock
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // should only be sent when a thread has relinquished the token.
a61af66fc99e Initial load
duke
parents:
diff changeset
98 //
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // In the absence of either property, we'd have potential deadlock.
a61af66fc99e Initial load
duke
parents:
diff changeset
100 //
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // We protect each of the CMS (concurrent and sequential) phases
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // with the CMS _token_, not the CMS _lock_.
a61af66fc99e Initial load
duke
parents:
diff changeset
103 //
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // The only code protected by CMS lock is the token acquisition code
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // itself, see ConcurrentMarkSweepThread::[de]synchronize(), and the
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // baton-passing code.
a61af66fc99e Initial load
duke
parents:
diff changeset
107 //
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // Unfortunately, i couldn't come up with a good abstraction to factor and
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // hide the naked CGC_lock manipulation in the baton-passing code
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // further below. That's something we should try to do. Also, the proof
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // of correctness of this 2-level locking scheme is far from obvious,
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // and potentially quite slippery. We have an uneasy supsicion, for instance,
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // that there may be a theoretical possibility of delay/starvation in the
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // low-level lock/wait/notify scheme used for the baton-passing because of
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // potential intereference with the priority scheme embodied in the
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // CMS-token-passing protocol. See related comments at a CGC_lock->wait()
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // invocation further below and marked with "XXX 20011219YSR".
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // Indeed, as we note elsewhere, this may become yet more slippery
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // in the presence of multiple CMS and/or multiple VM threads. XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 class CMSTokenSync: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
122 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
123 bool _is_cms_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
124 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
125 CMSTokenSync(bool is_cms_thread):
a61af66fc99e Initial load
duke
parents:
diff changeset
126 _is_cms_thread(is_cms_thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 assert(is_cms_thread == Thread::current()->is_ConcurrentGC_thread(),
a61af66fc99e Initial load
duke
parents:
diff changeset
128 "Incorrect argument to constructor");
a61af66fc99e Initial load
duke
parents:
diff changeset
129 ConcurrentMarkSweepThread::synchronize(_is_cms_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132 ~CMSTokenSync() {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 assert(_is_cms_thread ?
a61af66fc99e Initial load
duke
parents:
diff changeset
134 ConcurrentMarkSweepThread::cms_thread_has_cms_token() :
a61af66fc99e Initial load
duke
parents:
diff changeset
135 ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
136 "Incorrect state");
a61af66fc99e Initial load
duke
parents:
diff changeset
137 ConcurrentMarkSweepThread::desynchronize(_is_cms_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139 };
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // Convenience class that does a CMSTokenSync, and then acquires
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // upto three locks.
a61af66fc99e Initial load
duke
parents:
diff changeset
143 class CMSTokenSyncWithLocks: public CMSTokenSync {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // Note: locks are acquired in textual declaration order
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // and released in the opposite order
a61af66fc99e Initial load
duke
parents:
diff changeset
147 MutexLockerEx _locker1, _locker2, _locker3;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
149 CMSTokenSyncWithLocks(bool is_cms_thread, Mutex* mutex1,
a61af66fc99e Initial load
duke
parents:
diff changeset
150 Mutex* mutex2 = NULL, Mutex* mutex3 = NULL):
a61af66fc99e Initial load
duke
parents:
diff changeset
151 CMSTokenSync(is_cms_thread),
a61af66fc99e Initial load
duke
parents:
diff changeset
152 _locker1(mutex1, Mutex::_no_safepoint_check_flag),
a61af66fc99e Initial load
duke
parents:
diff changeset
153 _locker2(mutex2, Mutex::_no_safepoint_check_flag),
a61af66fc99e Initial load
duke
parents:
diff changeset
154 _locker3(mutex3, Mutex::_no_safepoint_check_flag)
a61af66fc99e Initial load
duke
parents:
diff changeset
155 { }
a61af66fc99e Initial load
duke
parents:
diff changeset
156 };
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // Wrapper class to temporarily disable icms during a foreground cms collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
160 class ICMSDisabler: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // The ctor disables icms and wakes up the thread so it notices the change;
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // the dtor re-enables icms. Note that the CMSCollector methods will check
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // CMSIncrementalMode.
a61af66fc99e Initial load
duke
parents:
diff changeset
165 ICMSDisabler() { CMSCollector::disable_icms(); CMSCollector::start_icms(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 ~ICMSDisabler() { CMSCollector::enable_icms(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
167 };
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 //////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // Concurrent Mark-Sweep Generation /////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
171 //////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
172
a61af66fc99e Initial load
duke
parents:
diff changeset
173 NOT_PRODUCT(CompactibleFreeListSpace* debug_cms_space;)
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // This struct contains per-thread things necessary to support parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // young-gen collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
177 class CMSParGCThreadState: public CHeapObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
178 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
179 CFLS_LAB lab;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 PromotionInfo promo;
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // Constructor.
a61af66fc99e Initial load
duke
parents:
diff changeset
183 CMSParGCThreadState(CompactibleFreeListSpace* cfls) : lab(cfls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 promo.setSpace(cfls);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
186 };
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(
a61af66fc99e Initial load
duke
parents:
diff changeset
189 ReservedSpace rs, size_t initial_byte_size, int level,
a61af66fc99e Initial load
duke
parents:
diff changeset
190 CardTableRS* ct, bool use_adaptive_freelists,
a61af66fc99e Initial load
duke
parents:
diff changeset
191 FreeBlockDictionary::DictionaryChoice dictionaryChoice) :
a61af66fc99e Initial load
duke
parents:
diff changeset
192 CardGeneration(rs, initial_byte_size, level, ct),
1571
2d127394260e 6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents: 1521
diff changeset
193 _dilatation_factor(((double)MinChunkSize)/((double)(CollectedHeap::min_fill_size()))),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
194 _debug_collection_type(Concurrent_collection_type)
a61af66fc99e Initial load
duke
parents:
diff changeset
195 {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 HeapWord* bottom = (HeapWord*) _virtual_space.low();
a61af66fc99e Initial load
duke
parents:
diff changeset
197 HeapWord* end = (HeapWord*) _virtual_space.high();
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 _direct_allocated_words = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
201 _numObjectsPromoted = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 _numWordsPromoted = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 _numObjectsAllocated = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
204 _numWordsAllocated = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 )
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 _cmsSpace = new CompactibleFreeListSpace(_bts, MemRegion(bottom, end),
a61af66fc99e Initial load
duke
parents:
diff changeset
208 use_adaptive_freelists,
a61af66fc99e Initial load
duke
parents:
diff changeset
209 dictionaryChoice);
a61af66fc99e Initial load
duke
parents:
diff changeset
210 NOT_PRODUCT(debug_cms_space = _cmsSpace;)
a61af66fc99e Initial load
duke
parents:
diff changeset
211 if (_cmsSpace == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 vm_exit_during_initialization(
a61af66fc99e Initial load
duke
parents:
diff changeset
213 "CompactibleFreeListSpace allocation failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 _cmsSpace->_gen = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 _gc_stats = new CMSGCStats();
a61af66fc99e Initial load
duke
parents:
diff changeset
218
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // Verify the assumption that FreeChunk::_prev and OopDesc::_klass
a61af66fc99e Initial load
duke
parents:
diff changeset
220 // offsets match. The ability to tell free chunks from objects
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // depends on this property.
a61af66fc99e Initial load
duke
parents:
diff changeset
222 debug_only(
a61af66fc99e Initial load
duke
parents:
diff changeset
223 FreeChunk* junk = NULL;
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
224 assert(UseCompressedOops ||
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
225 junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
226 "Offset of FreeChunk::_prev within FreeChunk must match"
a61af66fc99e Initial load
duke
parents:
diff changeset
227 " that of OopDesc::_klass within OopDesc");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 )
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
229 if (CollectedHeap::use_parallel_gc_threads()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
230 typedef CMSParGCThreadState* CMSParGCThreadStatePtr;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 _par_gc_thread_states =
a61af66fc99e Initial load
duke
parents:
diff changeset
232 NEW_C_HEAP_ARRAY(CMSParGCThreadStatePtr, ParallelGCThreads);
a61af66fc99e Initial load
duke
parents:
diff changeset
233 if (_par_gc_thread_states == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 vm_exit_during_initialization("Could not allocate par gc structs");
a61af66fc99e Initial load
duke
parents:
diff changeset
235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
236 for (uint i = 0; i < ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 _par_gc_thread_states[i] = new CMSParGCThreadState(cmsSpace());
a61af66fc99e Initial load
duke
parents:
diff changeset
238 if (_par_gc_thread_states[i] == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 vm_exit_during_initialization("Could not allocate par gc structs");
a61af66fc99e Initial load
duke
parents:
diff changeset
240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
243 _par_gc_thread_states = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
245 _incremental_collection_failed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // The "dilatation_factor" is the expansion that can occur on
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // account of the fact that the minimum object size in the CMS
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // generation may be larger than that in, say, a contiguous young
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // Ideally, in the calculation below, we'd compute the dilatation
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // factor as: MinChunkSize/(promoting_gen's min object size)
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // Since we do not have such a general query interface for the
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // promoting generation, we'll instead just use the mimimum
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // object size (which today is a header's worth of space);
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // note that all arithmetic is in units of HeapWords.
1571
2d127394260e 6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents: 1521
diff changeset
256 assert(MinChunkSize >= CollectedHeap::min_fill_size(), "just checking");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
257 assert(_dilatation_factor >= 1.0, "from previous assert");
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
260
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
261 // The field "_initiating_occupancy" represents the occupancy percentage
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
262 // at which we trigger a new collection cycle. Unless explicitly specified
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
263 // via CMSInitiating[Perm]OccupancyFraction (argument "io" below), it
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
264 // is calculated by:
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
265 //
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
266 // Let "f" be MinHeapFreeRatio in
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
267 //
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
268 // _intiating_occupancy = 100-f +
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
269 // f * (CMSTrigger[Perm]Ratio/100)
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
270 // where CMSTrigger[Perm]Ratio is the argument "tr" below.
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
271 //
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
272 // That is, if we assume the heap is at its desired maximum occupancy at the
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
273 // end of a collection, we let CMSTrigger[Perm]Ratio of the (purported) free
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
274 // space be allocated before initiating a new collection cycle.
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
275 //
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
276 void ConcurrentMarkSweepGeneration::init_initiating_occupancy(intx io, intx tr) {
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
277 assert(io <= 100 && tr >= 0 && tr <= 100, "Check the arguments");
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
278 if (io >= 0) {
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
279 _initiating_occupancy = (double)io / 100.0;
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
280 } else {
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
281 _initiating_occupancy = ((100 - MinHeapFreeRatio) +
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
282 (double)(tr * MinHeapFreeRatio) / 100.0)
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
283 / 100.0;
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
284 }
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
285 }
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
286
0
a61af66fc99e Initial load
duke
parents:
diff changeset
287 void ConcurrentMarkSweepGeneration::ref_processor_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 assert(collector() != NULL, "no collector");
a61af66fc99e Initial load
duke
parents:
diff changeset
289 collector()->ref_processor_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292 void CMSCollector::ref_processor_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
293 if (_ref_processor == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // Allocate and initialize a reference processor
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
295 _ref_processor =
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
296 new ReferenceProcessor(_span, // span
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
297 (ParallelGCThreads > 1) && ParallelRefProcEnabled, // mt processing
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
298 (int) ParallelGCThreads, // mt processing degree
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
299 _cmsGen->refs_discovery_is_mt(), // mt discovery
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
300 (int) MAX2(ConcGCThreads, ParallelGCThreads), // mt discovery degree
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
301 _cmsGen->refs_discovery_is_atomic(), // discovery is not atomic
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
302 &_is_alive_closure, // closure for liveness info
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
303 false); // next field updates do not need write barrier
0
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // Initialize the _ref_processor field of CMSGen
a61af66fc99e Initial load
duke
parents:
diff changeset
305 _cmsGen->set_ref_processor(_ref_processor);
a61af66fc99e Initial load
duke
parents:
diff changeset
306
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // Allocate a dummy ref processor for perm gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
308 ReferenceProcessor* rp2 = new ReferenceProcessor();
a61af66fc99e Initial load
duke
parents:
diff changeset
309 if (rp2 == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312 _permGen->set_ref_processor(rp2);
a61af66fc99e Initial load
duke
parents:
diff changeset
313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316 CMSAdaptiveSizePolicy* CMSCollector::size_policy() {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
318 assert(gch->kind() == CollectedHeap::GenCollectedHeap,
a61af66fc99e Initial load
duke
parents:
diff changeset
319 "Wrong type of heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
320 CMSAdaptiveSizePolicy* sp = (CMSAdaptiveSizePolicy*)
a61af66fc99e Initial load
duke
parents:
diff changeset
321 gch->gen_policy()->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
322 assert(sp->is_gc_cms_adaptive_size_policy(),
a61af66fc99e Initial load
duke
parents:
diff changeset
323 "Wrong type of size policy");
a61af66fc99e Initial load
duke
parents:
diff changeset
324 return sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 CMSGCAdaptivePolicyCounters* CMSCollector::gc_adaptive_policy_counters() {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 CMSGCAdaptivePolicyCounters* results =
a61af66fc99e Initial load
duke
parents:
diff changeset
329 (CMSGCAdaptivePolicyCounters*) collector_policy()->counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
330 assert(
a61af66fc99e Initial load
duke
parents:
diff changeset
331 results->kind() == GCPolicyCounters::CMSGCAdaptivePolicyCountersKind,
a61af66fc99e Initial load
duke
parents:
diff changeset
332 "Wrong gc policy counter kind");
a61af66fc99e Initial load
duke
parents:
diff changeset
333 return results;
a61af66fc99e Initial load
duke
parents:
diff changeset
334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 const char* gen_name = "old";
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Generation Counters - generation 1, 1 subspace
a61af66fc99e Initial load
duke
parents:
diff changeset
342 _gen_counters = new GenerationCounters(gen_name, 1, 1, &_virtual_space);
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 _space_counters = new GSpaceCounters(gen_name, 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
345 _virtual_space.reserved_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
346 this, _gen_counters);
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 CMSStats::CMSStats(ConcurrentMarkSweepGeneration* cms_gen, unsigned int alpha):
a61af66fc99e Initial load
duke
parents:
diff changeset
350 _cms_gen(cms_gen)
a61af66fc99e Initial load
duke
parents:
diff changeset
351 {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 assert(alpha <= 100, "bad value");
a61af66fc99e Initial load
duke
parents:
diff changeset
353 _saved_alpha = alpha;
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // Initialize the alphas to the bootstrap value of 100.
a61af66fc99e Initial load
duke
parents:
diff changeset
356 _gc0_alpha = _cms_alpha = 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 _cms_begin_time.update();
a61af66fc99e Initial load
duke
parents:
diff changeset
359 _cms_end_time.update();
a61af66fc99e Initial load
duke
parents:
diff changeset
360
a61af66fc99e Initial load
duke
parents:
diff changeset
361 _gc0_duration = 0.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
362 _gc0_period = 0.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
363 _gc0_promoted = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 _cms_duration = 0.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
366 _cms_period = 0.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
367 _cms_allocated = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
368
a61af66fc99e Initial load
duke
parents:
diff changeset
369 _cms_used_at_gc0_begin = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 _cms_used_at_gc0_end = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
371 _allow_duty_cycle_reduction = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
372 _valid_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
373 _icms_duty_cycle = CMSIncrementalDutyCycle;
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
376 double CMSStats::cms_free_adjustment_factor(size_t free) const {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
377 // TBD: CR 6909490
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
378 return 1.0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
379 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
380
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
381 void CMSStats::adjust_cms_free_adjustment_factor(bool fail, size_t free) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
382 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
383
0
a61af66fc99e Initial load
duke
parents:
diff changeset
384 // If promotion failure handling is on use
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // the padded average size of the promotion for each
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // young generation collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
387 double CMSStats::time_until_cms_gen_full() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 size_t cms_free = _cms_gen->cmsSpace()->free();
a61af66fc99e Initial load
duke
parents:
diff changeset
389 GenCollectedHeap* gch = GenCollectedHeap::heap();
1888
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
390 size_t expected_promotion = MIN2(gch->get_gen(0)->capacity(),
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
391 (size_t) _cms_gen->gc_stats()->avg_promoted()->padded_average());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
392 if (cms_free > expected_promotion) {
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // Start a cms collection if there isn't enough space to promote
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // for the next minor collection. Use the padded average as
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // a safety factor.
a61af66fc99e Initial load
duke
parents:
diff changeset
396 cms_free -= expected_promotion;
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // Adjust by the safety factor.
a61af66fc99e Initial load
duke
parents:
diff changeset
399 double cms_free_dbl = (double)cms_free;
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
400 double cms_adjustment = (100.0 - CMSIncrementalSafetyFactor)/100.0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
401 // Apply a further correction factor which tries to adjust
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
402 // for recent occurance of concurrent mode failures.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
403 cms_adjustment = cms_adjustment * cms_free_adjustment_factor(cms_free);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
404 cms_free_dbl = cms_free_dbl * cms_adjustment;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 gclog_or_tty->print_cr("CMSStats::time_until_cms_gen_full: cms_free "
a61af66fc99e Initial load
duke
parents:
diff changeset
408 SIZE_FORMAT " expected_promotion " SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
409 cms_free, expected_promotion);
a61af66fc99e Initial load
duke
parents:
diff changeset
410 gclog_or_tty->print_cr(" cms_free_dbl %f cms_consumption_rate %f",
a61af66fc99e Initial load
duke
parents:
diff changeset
411 cms_free_dbl, cms_consumption_rate() + 1.0);
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // Add 1 in case the consumption rate goes to zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
414 return cms_free_dbl / (cms_consumption_rate() + 1.0);
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
416 return 0.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // Compare the duration of the cms collection to the
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // time remaining before the cms generation is empty.
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // Note that the time from the start of the cms collection
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // to the start of the cms sweep (less than the total
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // duration of the cms collection) can be used. This
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // has been tried and some applications experienced
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // promotion failures early in execution. This was
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // possibly because the averages were not accurate
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // enough at the beginning.
a61af66fc99e Initial load
duke
parents:
diff changeset
428 double CMSStats::time_until_cms_start() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // We add "gc0_period" to the "work" calculation
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // below because this query is done (mostly) at the
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // end of a scavenge, so we need to conservatively
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // account for that much possible delay
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // in the query so as to avoid concurrent mode failures
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // due to starting the collection just a wee bit too
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // late.
a61af66fc99e Initial load
duke
parents:
diff changeset
436 double work = cms_duration() + gc0_period();
a61af66fc99e Initial load
duke
parents:
diff changeset
437 double deadline = time_until_cms_gen_full();
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
438 // If a concurrent mode failure occurred recently, we want to be
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
439 // more conservative and halve our expected time_until_cms_gen_full()
0
a61af66fc99e Initial load
duke
parents:
diff changeset
440 if (work > deadline) {
a61af66fc99e Initial load
duke
parents:
diff changeset
441 if (Verbose && PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
442 gclog_or_tty->print(
a61af66fc99e Initial load
duke
parents:
diff changeset
443 " CMSCollector: collect because of anticipated promotion "
a61af66fc99e Initial load
duke
parents:
diff changeset
444 "before full %3.7f + %3.7f > %3.7f ", cms_duration(),
a61af66fc99e Initial load
duke
parents:
diff changeset
445 gc0_period(), time_until_cms_gen_full());
a61af66fc99e Initial load
duke
parents:
diff changeset
446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
447 return 0.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
449 return work - deadline;
a61af66fc99e Initial load
duke
parents:
diff changeset
450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // Return a duty cycle based on old_duty_cycle and new_duty_cycle, limiting the
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // amount of change to prevent wild oscillation.
a61af66fc99e Initial load
duke
parents:
diff changeset
454 unsigned int CMSStats::icms_damped_duty_cycle(unsigned int old_duty_cycle,
a61af66fc99e Initial load
duke
parents:
diff changeset
455 unsigned int new_duty_cycle) {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 assert(old_duty_cycle <= 100, "bad input value");
a61af66fc99e Initial load
duke
parents:
diff changeset
457 assert(new_duty_cycle <= 100, "bad input value");
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // Note: use subtraction with caution since it may underflow (values are
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // unsigned). Addition is safe since we're in the range 0-100.
a61af66fc99e Initial load
duke
parents:
diff changeset
461 unsigned int damped_duty_cycle = new_duty_cycle;
a61af66fc99e Initial load
duke
parents:
diff changeset
462 if (new_duty_cycle < old_duty_cycle) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 5U);
a61af66fc99e Initial load
duke
parents:
diff changeset
464 if (new_duty_cycle + largest_delta < old_duty_cycle) {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 damped_duty_cycle = old_duty_cycle - largest_delta;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467 } else if (new_duty_cycle > old_duty_cycle) {
a61af66fc99e Initial load
duke
parents:
diff changeset
468 const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 15U);
a61af66fc99e Initial load
duke
parents:
diff changeset
469 if (new_duty_cycle > old_duty_cycle + largest_delta) {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 damped_duty_cycle = MIN2(old_duty_cycle + largest_delta, 100U);
a61af66fc99e Initial load
duke
parents:
diff changeset
471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473 assert(damped_duty_cycle <= 100, "invalid duty cycle computed");
a61af66fc99e Initial load
duke
parents:
diff changeset
474
a61af66fc99e Initial load
duke
parents:
diff changeset
475 if (CMSTraceIncrementalPacing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 gclog_or_tty->print(" [icms_damped_duty_cycle(%d,%d) = %d] ",
a61af66fc99e Initial load
duke
parents:
diff changeset
477 old_duty_cycle, new_duty_cycle, damped_duty_cycle);
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479 return damped_duty_cycle;
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 unsigned int CMSStats::icms_update_duty_cycle_impl() {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 assert(CMSIncrementalPacing && valid(),
a61af66fc99e Initial load
duke
parents:
diff changeset
484 "should be handled in icms_update_duty_cycle()");
a61af66fc99e Initial load
duke
parents:
diff changeset
485
a61af66fc99e Initial load
duke
parents:
diff changeset
486 double cms_time_so_far = cms_timer().seconds();
a61af66fc99e Initial load
duke
parents:
diff changeset
487 double scaled_duration = cms_duration_per_mb() * _cms_used_at_gc0_end / M;
a61af66fc99e Initial load
duke
parents:
diff changeset
488 double scaled_duration_remaining = fabsd(scaled_duration - cms_time_so_far);
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // Avoid division by 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
491 double time_until_full = MAX2(time_until_cms_gen_full(), 0.01);
a61af66fc99e Initial load
duke
parents:
diff changeset
492 double duty_cycle_dbl = 100.0 * scaled_duration_remaining / time_until_full;
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494 unsigned int new_duty_cycle = MIN2((unsigned int)duty_cycle_dbl, 100U);
a61af66fc99e Initial load
duke
parents:
diff changeset
495 if (new_duty_cycle > _icms_duty_cycle) {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // Avoid very small duty cycles (1 or 2); 0 is allowed.
a61af66fc99e Initial load
duke
parents:
diff changeset
497 if (new_duty_cycle > 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 _icms_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle,
a61af66fc99e Initial load
duke
parents:
diff changeset
499 new_duty_cycle);
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501 } else if (_allow_duty_cycle_reduction) {
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // The duty cycle is reduced only once per cms cycle (see record_cms_end()).
a61af66fc99e Initial load
duke
parents:
diff changeset
503 new_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle, new_duty_cycle);
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // Respect the minimum duty cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
505 unsigned int min_duty_cycle = (unsigned int)CMSIncrementalDutyCycleMin;
a61af66fc99e Initial load
duke
parents:
diff changeset
506 _icms_duty_cycle = MAX2(new_duty_cycle, min_duty_cycle);
a61af66fc99e Initial load
duke
parents:
diff changeset
507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
508
a61af66fc99e Initial load
duke
parents:
diff changeset
509 if (PrintGCDetails || CMSTraceIncrementalPacing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
510 gclog_or_tty->print(" icms_dc=%d ", _icms_duty_cycle);
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 _allow_duty_cycle_reduction = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
514 return _icms_duty_cycle;
a61af66fc99e Initial load
duke
parents:
diff changeset
515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
516
a61af66fc99e Initial load
duke
parents:
diff changeset
517 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
518 void CMSStats::print_on(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 st->print(" gc0_alpha=%d,cms_alpha=%d", _gc0_alpha, _cms_alpha);
a61af66fc99e Initial load
duke
parents:
diff changeset
520 st->print(",gc0_dur=%g,gc0_per=%g,gc0_promo=" SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
521 gc0_duration(), gc0_period(), gc0_promoted());
a61af66fc99e Initial load
duke
parents:
diff changeset
522 st->print(",cms_dur=%g,cms_dur_per_mb=%g,cms_per=%g,cms_alloc=" SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
523 cms_duration(), cms_duration_per_mb(),
a61af66fc99e Initial load
duke
parents:
diff changeset
524 cms_period(), cms_allocated());
a61af66fc99e Initial load
duke
parents:
diff changeset
525 st->print(",cms_since_beg=%g,cms_since_end=%g",
a61af66fc99e Initial load
duke
parents:
diff changeset
526 cms_time_since_begin(), cms_time_since_end());
a61af66fc99e Initial load
duke
parents:
diff changeset
527 st->print(",cms_used_beg=" SIZE_FORMAT ",cms_used_end=" SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
528 _cms_used_at_gc0_begin, _cms_used_at_gc0_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
529 if (CMSIncrementalMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 st->print(",dc=%d", icms_duty_cycle());
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 if (valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 st->print(",promo_rate=%g,cms_alloc_rate=%g",
a61af66fc99e Initial load
duke
parents:
diff changeset
535 promotion_rate(), cms_allocation_rate());
a61af66fc99e Initial load
duke
parents:
diff changeset
536 st->print(",cms_consumption_rate=%g,time_until_full=%g",
a61af66fc99e Initial load
duke
parents:
diff changeset
537 cms_consumption_rate(), time_until_cms_gen_full());
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541 #endif // #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
542
a61af66fc99e Initial load
duke
parents:
diff changeset
543 CMSCollector::CollectorState CMSCollector::_collectorState =
a61af66fc99e Initial load
duke
parents:
diff changeset
544 CMSCollector::Idling;
a61af66fc99e Initial load
duke
parents:
diff changeset
545 bool CMSCollector::_foregroundGCIsActive = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
546 bool CMSCollector::_foregroundGCShouldWait = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
a61af66fc99e Initial load
duke
parents:
diff changeset
549 ConcurrentMarkSweepGeneration* permGen,
a61af66fc99e Initial load
duke
parents:
diff changeset
550 CardTableRS* ct,
a61af66fc99e Initial load
duke
parents:
diff changeset
551 ConcurrentMarkSweepPolicy* cp):
a61af66fc99e Initial load
duke
parents:
diff changeset
552 _cmsGen(cmsGen),
a61af66fc99e Initial load
duke
parents:
diff changeset
553 _permGen(permGen),
a61af66fc99e Initial load
duke
parents:
diff changeset
554 _ct(ct),
a61af66fc99e Initial load
duke
parents:
diff changeset
555 _ref_processor(NULL), // will be set later
a61af66fc99e Initial load
duke
parents:
diff changeset
556 _conc_workers(NULL), // may be set later
a61af66fc99e Initial load
duke
parents:
diff changeset
557 _abort_preclean(false),
a61af66fc99e Initial load
duke
parents:
diff changeset
558 _start_sampling(false),
a61af66fc99e Initial load
duke
parents:
diff changeset
559 _between_prologue_and_epilogue(false),
a61af66fc99e Initial load
duke
parents:
diff changeset
560 _markBitMap(0, Mutex::leaf + 1, "CMS_markBitMap_lock"),
a61af66fc99e Initial load
duke
parents:
diff changeset
561 _perm_gen_verify_bit_map(0, -1 /* no mutex */, "No_lock"),
a61af66fc99e Initial load
duke
parents:
diff changeset
562 _modUnionTable((CardTableModRefBS::card_shift - LogHeapWordSize),
a61af66fc99e Initial load
duke
parents:
diff changeset
563 -1 /* lock-free */, "No_lock" /* dummy */),
a61af66fc99e Initial load
duke
parents:
diff changeset
564 _modUnionClosure(&_modUnionTable),
a61af66fc99e Initial load
duke
parents:
diff changeset
565 _modUnionClosurePar(&_modUnionTable),
143
b5489bb705c9 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 113
diff changeset
566 // Adjust my span to cover old (cms) gen and perm gen
b5489bb705c9 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 113
diff changeset
567 _span(cmsGen->reserved()._union(permGen->reserved())),
b5489bb705c9 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 113
diff changeset
568 // Construct the is_alive_closure with _span & markBitMap
b5489bb705c9 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 113
diff changeset
569 _is_alive_closure(_span, &_markBitMap),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
570 _restart_addr(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
571 _overflow_list(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
572 _stats(cmsGen),
a61af66fc99e Initial load
duke
parents:
diff changeset
573 _eden_chunk_array(NULL), // may be set in ctor body
a61af66fc99e Initial load
duke
parents:
diff changeset
574 _eden_chunk_capacity(0), // -- ditto --
a61af66fc99e Initial load
duke
parents:
diff changeset
575 _eden_chunk_index(0), // -- ditto --
a61af66fc99e Initial load
duke
parents:
diff changeset
576 _survivor_plab_array(NULL), // -- ditto --
a61af66fc99e Initial load
duke
parents:
diff changeset
577 _survivor_chunk_array(NULL), // -- ditto --
a61af66fc99e Initial load
duke
parents:
diff changeset
578 _survivor_chunk_capacity(0), // -- ditto --
a61af66fc99e Initial load
duke
parents:
diff changeset
579 _survivor_chunk_index(0), // -- ditto --
a61af66fc99e Initial load
duke
parents:
diff changeset
580 _ser_pmc_preclean_ovflw(0),
452
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
581 _ser_kac_preclean_ovflw(0),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
582 _ser_pmc_remark_ovflw(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
583 _par_pmc_remark_ovflw(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
584 _ser_kac_ovflw(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
585 _par_kac_ovflw(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
586 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
587 _num_par_pushes(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
588 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
589 _collection_count_start(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
590 _verifying(false),
a61af66fc99e Initial load
duke
parents:
diff changeset
591 _icms_start_limit(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
592 _icms_stop_limit(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
593 _verification_mark_bm(0, Mutex::leaf + 1, "CMS_verification_mark_bm_lock"),
a61af66fc99e Initial load
duke
parents:
diff changeset
594 _completed_initialization(false),
a61af66fc99e Initial load
duke
parents:
diff changeset
595 _collector_policy(cp),
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
596 _should_unload_classes(false),
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
597 _concurrent_cycles_since_last_unload(0),
798
fe1574da39fc 6848641: CMSCollector::_roots_scanning_options should be initialized
ysr
parents: 679
diff changeset
598 _roots_scanning_options(0),
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
599 _inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
600 _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
601 {
a61af66fc99e Initial load
duke
parents:
diff changeset
602 if (ExplicitGCInvokesConcurrentAndUnloadsClasses) {
a61af66fc99e Initial load
duke
parents:
diff changeset
603 ExplicitGCInvokesConcurrent = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // Now expand the span and allocate the collection support structures
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // (MUT, marking bit map etc.) to cover both generations subject to
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // First check that _permGen is adjacent to _cmsGen and above it.
a61af66fc99e Initial load
duke
parents:
diff changeset
610 assert( _cmsGen->reserved().word_size() > 0
a61af66fc99e Initial load
duke
parents:
diff changeset
611 && _permGen->reserved().word_size() > 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
612 "generations should not be of zero size");
a61af66fc99e Initial load
duke
parents:
diff changeset
613 assert(_cmsGen->reserved().intersection(_permGen->reserved()).is_empty(),
a61af66fc99e Initial load
duke
parents:
diff changeset
614 "_cmsGen and _permGen should not overlap");
a61af66fc99e Initial load
duke
parents:
diff changeset
615 assert(_cmsGen->reserved().end() == _permGen->reserved().start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
616 "_cmsGen->end() different from _permGen->start()");
a61af66fc99e Initial load
duke
parents:
diff changeset
617
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // For use by dirty card to oop closures.
a61af66fc99e Initial load
duke
parents:
diff changeset
619 _cmsGen->cmsSpace()->set_collector(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
620 _permGen->cmsSpace()->set_collector(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // Allocate MUT and marking bit map
a61af66fc99e Initial load
duke
parents:
diff changeset
623 {
a61af66fc99e Initial load
duke
parents:
diff changeset
624 MutexLockerEx x(_markBitMap.lock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
625 if (!_markBitMap.allocate(_span)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
626 warning("Failed to allocate CMS Bit Map");
a61af66fc99e Initial load
duke
parents:
diff changeset
627 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
629 assert(_markBitMap.covers(_span), "_markBitMap inconsistency?");
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631 {
a61af66fc99e Initial load
duke
parents:
diff changeset
632 _modUnionTable.allocate(_span);
a61af66fc99e Initial load
duke
parents:
diff changeset
633 assert(_modUnionTable.covers(_span), "_modUnionTable inconsistency?");
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
636 if (!_markStack.allocate(MarkStackSize)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
637 warning("Failed to allocate CMS Marking Stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
638 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
640 if (!_revisitStack.allocate(CMSRevisitStackSize)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
641 warning("Failed to allocate CMS Revisit Stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
642 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // Support for multi-threaded concurrent phases
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
646 if (CMSConcurrentMTEnabled) {
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
647 if (FLAG_IS_DEFAULT(ConcGCThreads)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // just for now
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
649 FLAG_SET_DEFAULT(ConcGCThreads, (ParallelGCThreads + 3)/4);
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
650 }
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
651 if (ConcGCThreads > 1) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
652 _conc_workers = new YieldingFlexibleWorkGang("Parallel CMS Threads",
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
653 ConcGCThreads, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
654 if (_conc_workers == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
655 warning("GC/CMS: _conc_workers allocation failure: "
a61af66fc99e Initial load
duke
parents:
diff changeset
656 "forcing -CMSConcurrentMTEnabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
657 CMSConcurrentMTEnabled = false;
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
658 } else {
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
659 _conc_workers->initialize_workers();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
661 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
662 CMSConcurrentMTEnabled = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
665 if (!CMSConcurrentMTEnabled) {
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
666 ConcGCThreads = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
667 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // Turn off CMSCleanOnEnter optimization temporarily for
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // the MT case where it's not fixed yet; see 6178663.
a61af66fc99e Initial load
duke
parents:
diff changeset
670 CMSCleanOnEnter = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
671 }
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
672 assert((_conc_workers != NULL) == (ConcGCThreads > 1),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
673 "Inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
674
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // Parallel task queues; these are shared for the
a61af66fc99e Initial load
duke
parents:
diff changeset
676 // concurrent and stop-world phases of CMS, but
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // are not shared with parallel scavenge (ParNew).
a61af66fc99e Initial load
duke
parents:
diff changeset
678 {
a61af66fc99e Initial load
duke
parents:
diff changeset
679 uint i;
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
680 uint num_queues = (uint) MAX2(ParallelGCThreads, ConcGCThreads);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
681
a61af66fc99e Initial load
duke
parents:
diff changeset
682 if ((CMSParallelRemarkEnabled || CMSConcurrentMTEnabled
a61af66fc99e Initial load
duke
parents:
diff changeset
683 || ParallelRefProcEnabled)
a61af66fc99e Initial load
duke
parents:
diff changeset
684 && num_queues > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
685 _task_queues = new OopTaskQueueSet(num_queues);
a61af66fc99e Initial load
duke
parents:
diff changeset
686 if (_task_queues == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
687 warning("task_queues allocation failure.");
a61af66fc99e Initial load
duke
parents:
diff changeset
688 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
690 _hash_seed = NEW_C_HEAP_ARRAY(int, num_queues);
a61af66fc99e Initial load
duke
parents:
diff changeset
691 if (_hash_seed == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 warning("_hash_seed array allocation failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
693 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1579
diff changeset
696 typedef Padded<OopTaskQueue> PaddedOopTaskQueue;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
697 for (i = 0; i < num_queues; i++) {
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1579
diff changeset
698 PaddedOopTaskQueue *q = new PaddedOopTaskQueue();
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1579
diff changeset
699 if (q == NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
700 warning("work_queue allocation failure.");
a61af66fc99e Initial load
duke
parents:
diff changeset
701 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1579
diff changeset
703 _task_queues->register_queue(i, q);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
705 for (i = 0; i < num_queues; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
706 _task_queues->queue(i)->initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
707 _hash_seed[i] = 17; // copied from ParNew
a61af66fc99e Initial load
duke
parents:
diff changeset
708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
709 }
a61af66fc99e Initial load
duke
parents:
diff changeset
710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
711
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
712 _cmsGen ->init_initiating_occupancy(CMSInitiatingOccupancyFraction, CMSTriggerRatio);
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
713 _permGen->init_initiating_occupancy(CMSInitiatingPermOccupancyFraction, CMSTriggerPermRatio);
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
714
0
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // Clip CMSBootstrapOccupancy between 0 and 100.
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
716 _bootstrap_occupancy = ((double)MIN2((uintx)100, MAX2((uintx)0, CMSBootstrapOccupancy)))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
717 /(double)100;
a61af66fc99e Initial load
duke
parents:
diff changeset
718
a61af66fc99e Initial load
duke
parents:
diff changeset
719 _full_gcs_since_conc_gc = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
720
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // Now tell CMS generations the identity of their collector
a61af66fc99e Initial load
duke
parents:
diff changeset
722 ConcurrentMarkSweepGeneration::set_collector(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 // Create & start a CMS thread for this CMS collector
a61af66fc99e Initial load
duke
parents:
diff changeset
725 _cmsThread = ConcurrentMarkSweepThread::start(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
726 assert(cmsThread() != NULL, "CMS Thread should have been created");
a61af66fc99e Initial load
duke
parents:
diff changeset
727 assert(cmsThread()->collector() == this,
a61af66fc99e Initial load
duke
parents:
diff changeset
728 "CMS Thread should refer to this gen");
a61af66fc99e Initial load
duke
parents:
diff changeset
729 assert(CGC_lock != NULL, "Where's the CGC_lock?");
a61af66fc99e Initial load
duke
parents:
diff changeset
730
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // Support for parallelizing young gen rescan
a61af66fc99e Initial load
duke
parents:
diff changeset
732 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
733 _young_gen = gch->prev_gen(_cmsGen);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 if (gch->supports_inline_contig_alloc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
735 _top_addr = gch->top_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
736 _end_addr = gch->end_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
737 assert(_young_gen != NULL, "no _young_gen");
a61af66fc99e Initial load
duke
parents:
diff changeset
738 _eden_chunk_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
739 _eden_chunk_capacity = (_young_gen->max_capacity()+CMSSamplingGrain)/CMSSamplingGrain;
a61af66fc99e Initial load
duke
parents:
diff changeset
740 _eden_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, _eden_chunk_capacity);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 if (_eden_chunk_array == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 _eden_chunk_capacity = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
743 warning("GC/CMS: _eden_chunk_array allocation failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
746 assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error");
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // Support for parallelizing survivor space rescan
a61af66fc99e Initial load
duke
parents:
diff changeset
749 if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
1289
d47555d7aca8 6910182: CMS: assert(_cursor[j] == _survivor_plab_array[j].end(),"Ctl pt invariant")
jmasa
parents: 1284
diff changeset
750 const size_t max_plab_samples =
d47555d7aca8 6910182: CMS: assert(_cursor[j] == _survivor_plab_array[j].end(),"Ctl pt invariant")
jmasa
parents: 1284
diff changeset
751 ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
d47555d7aca8 6910182: CMS: assert(_cursor[j] == _survivor_plab_array[j].end(),"Ctl pt invariant")
jmasa
parents: 1284
diff changeset
752
0
a61af66fc99e Initial load
duke
parents:
diff changeset
753 _survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
a61af66fc99e Initial load
duke
parents:
diff changeset
754 _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
a61af66fc99e Initial load
duke
parents:
diff changeset
755 _cursor = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
a61af66fc99e Initial load
duke
parents:
diff changeset
756 if (_survivor_plab_array == NULL || _survivor_chunk_array == NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
757 || _cursor == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
758 warning("Failed to allocate survivor plab/chunk array");
a61af66fc99e Initial load
duke
parents:
diff changeset
759 if (_survivor_plab_array != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
760 FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
a61af66fc99e Initial load
duke
parents:
diff changeset
761 _survivor_plab_array = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
763 if (_survivor_chunk_array != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
764 FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
a61af66fc99e Initial load
duke
parents:
diff changeset
765 _survivor_chunk_array = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
767 if (_cursor != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
768 FREE_C_HEAP_ARRAY(size_t, _cursor);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 _cursor = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
771 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 _survivor_chunk_capacity = 2*max_plab_samples;
a61af66fc99e Initial load
duke
parents:
diff changeset
773 for (uint i = 0; i < ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
774 HeapWord** vec = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples);
a61af66fc99e Initial load
duke
parents:
diff changeset
775 if (vec == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 warning("Failed to allocate survivor plab array");
a61af66fc99e Initial load
duke
parents:
diff changeset
777 for (int j = i; j > 0; j--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
778 FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array());
a61af66fc99e Initial load
duke
parents:
diff changeset
779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
780 FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
a61af66fc99e Initial load
duke
parents:
diff changeset
781 FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
a61af66fc99e Initial load
duke
parents:
diff changeset
782 _survivor_plab_array = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
783 _survivor_chunk_array = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
784 _survivor_chunk_capacity = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
785 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
786 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
787 ChunkArray* cur =
a61af66fc99e Initial load
duke
parents:
diff changeset
788 ::new (&_survivor_plab_array[i]) ChunkArray(vec,
a61af66fc99e Initial load
duke
parents:
diff changeset
789 max_plab_samples);
a61af66fc99e Initial load
duke
parents:
diff changeset
790 assert(cur->end() == 0, "Should be 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
791 assert(cur->array() == vec, "Should be vec");
a61af66fc99e Initial load
duke
parents:
diff changeset
792 assert(cur->capacity() == max_plab_samples, "Error");
a61af66fc99e Initial load
duke
parents:
diff changeset
793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
794 }
a61af66fc99e Initial load
duke
parents:
diff changeset
795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
797 assert( ( _survivor_plab_array != NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
798 && _survivor_chunk_array != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
799 || ( _survivor_chunk_capacity == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
800 && _survivor_chunk_index == 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
801 "Error");
a61af66fc99e Initial load
duke
parents:
diff changeset
802
a61af66fc99e Initial load
duke
parents:
diff changeset
803 // Choose what strong roots should be scanned depending on verification options
a61af66fc99e Initial load
duke
parents:
diff changeset
804 // and perm gen collection mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
805 if (!CMSClassUnloadingEnabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // If class unloading is disabled we want to include all classes into the root set.
a61af66fc99e Initial load
duke
parents:
diff changeset
807 add_root_scanning_option(SharedHeap::SO_AllClasses);
a61af66fc99e Initial load
duke
parents:
diff changeset
808 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
809 add_root_scanning_option(SharedHeap::SO_SystemClasses);
a61af66fc99e Initial load
duke
parents:
diff changeset
810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 NOT_PRODUCT(_overflow_counter = CMSMarkStackOverflowInterval;)
a61af66fc99e Initial load
duke
parents:
diff changeset
813 _gc_counters = new CollectorCounters("CMS", 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
814 _completed_initialization = true;
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
815 _inter_sweep_timer.start(); // start of time
1518
3bfae429e2cf 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 1387
diff changeset
816 #ifdef SPARC
3bfae429e2cf 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 1387
diff changeset
817 // Issue a stern warning, but allow use for experimentation and debugging.
3bfae429e2cf 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 1387
diff changeset
818 if (VM_Version::is_sun4v() && UseMemSetInBOT) {
3bfae429e2cf 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 1387
diff changeset
819 assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error");
3bfae429e2cf 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 1387
diff changeset
820 warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability"
3bfae429e2cf 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 1387
diff changeset
821 " on sun4v; please understand that you are using at your own risk!");
3bfae429e2cf 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 1387
diff changeset
822 }
3bfae429e2cf 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 1387
diff changeset
823 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 const char* ConcurrentMarkSweepGeneration::name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
827 return "concurrent mark-sweep generation";
a61af66fc99e Initial load
duke
parents:
diff changeset
828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
829 void ConcurrentMarkSweepGeneration::update_counters() {
a61af66fc99e Initial load
duke
parents:
diff changeset
830 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
831 _space_counters->update_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
832 _gen_counters->update_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
834 }
a61af66fc99e Initial load
duke
parents:
diff changeset
835
a61af66fc99e Initial load
duke
parents:
diff changeset
836 // this is an optimized version of update_counters(). it takes the
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // used value as a parameter rather than computing it.
a61af66fc99e Initial load
duke
parents:
diff changeset
838 //
a61af66fc99e Initial load
duke
parents:
diff changeset
839 void ConcurrentMarkSweepGeneration::update_counters(size_t used) {
a61af66fc99e Initial load
duke
parents:
diff changeset
840 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
841 _space_counters->update_used(used);
a61af66fc99e Initial load
duke
parents:
diff changeset
842 _space_counters->update_capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
843 _gen_counters->update_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
844 }
a61af66fc99e Initial load
duke
parents:
diff changeset
845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
846
a61af66fc99e Initial load
duke
parents:
diff changeset
847 void ConcurrentMarkSweepGeneration::print() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
848 Generation::print();
a61af66fc99e Initial load
duke
parents:
diff changeset
849 cmsSpace()->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
851
a61af66fc99e Initial load
duke
parents:
diff changeset
852 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
853 void ConcurrentMarkSweepGeneration::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
854 cmsSpace()->printFLCensus(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
857
a61af66fc99e Initial load
duke
parents:
diff changeset
858 void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
859 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
860 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
861 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
862 gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]",
a61af66fc99e Initial load
duke
parents:
diff changeset
863 level(), short_name(), s, used(), capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
864 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
865 gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]",
a61af66fc99e Initial load
duke
parents:
diff changeset
866 level(), short_name(), s, used() / K, capacity() / K);
a61af66fc99e Initial load
duke
parents:
diff changeset
867 }
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
870 gclog_or_tty->print(" "SIZE_FORMAT"("SIZE_FORMAT")",
a61af66fc99e Initial load
duke
parents:
diff changeset
871 gch->used(), gch->capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
872 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 gclog_or_tty->print(" "SIZE_FORMAT"K("SIZE_FORMAT"K)",
a61af66fc99e Initial load
duke
parents:
diff changeset
874 gch->used() / K, gch->capacity() / K);
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876 }
a61af66fc99e Initial load
duke
parents:
diff changeset
877
a61af66fc99e Initial load
duke
parents:
diff changeset
878 size_t
a61af66fc99e Initial load
duke
parents:
diff changeset
879 ConcurrentMarkSweepGeneration::contiguous_available() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // dld proposes an improvement in precision here. If the committed
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // part of the space ends in a free block we should add that to
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // uncommitted size in the calculation below. Will make this
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // change later, staying with the approximation below for the
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // time being. -- ysr.
a61af66fc99e Initial load
duke
parents:
diff changeset
885 return MAX2(_virtual_space.uncommitted_size(), unsafe_max_alloc_nogc());
a61af66fc99e Initial load
duke
parents:
diff changeset
886 }
a61af66fc99e Initial load
duke
parents:
diff changeset
887
a61af66fc99e Initial load
duke
parents:
diff changeset
888 size_t
a61af66fc99e Initial load
duke
parents:
diff changeset
889 ConcurrentMarkSweepGeneration::unsafe_max_alloc_nogc() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
890 return _cmsSpace->max_alloc_in_words() * HeapWordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
892
a61af66fc99e Initial load
duke
parents:
diff changeset
893 size_t ConcurrentMarkSweepGeneration::max_available() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
894 return free() + _virtual_space.uncommitted_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
896
1888
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
897 bool ConcurrentMarkSweepGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const {
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
898 size_t available = max_available();
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
899 size_t av_promo = (size_t)gc_stats()->avg_promoted()->padded_average();
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
900 bool res = (available >= av_promo) || (available >= max_promotion_in_bytes);
1994
6cd6d394f280 7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
ysr
parents: 1972
diff changeset
901 if (Verbose && PrintGCDetails) {
1888
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
902 gclog_or_tty->print_cr(
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
903 "CMS: promo attempt is%s safe: available("SIZE_FORMAT") %s av_promo("SIZE_FORMAT"),"
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
904 "max_promo("SIZE_FORMAT")",
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
905 res? "":" not", available, res? ">=":"<",
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
906 av_promo, max_promotion_in_bytes);
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
907 }
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
908 return res;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
910
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
911 // At a promotion failure dump information on block layout in heap
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
912 // (cms old generation).
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
913 void ConcurrentMarkSweepGeneration::promotion_failure_occurred() {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
914 if (CMSDumpAtPromotionFailure) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
915 cmsSpace()->dump_at_safepoint_with_locks(collector(), gclog_or_tty);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
916 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
917 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
918
0
a61af66fc99e Initial load
duke
parents:
diff changeset
919 CompactibleSpace*
a61af66fc99e Initial load
duke
parents:
diff changeset
920 ConcurrentMarkSweepGeneration::first_compaction_space() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
921 return _cmsSpace;
a61af66fc99e Initial load
duke
parents:
diff changeset
922 }
a61af66fc99e Initial load
duke
parents:
diff changeset
923
a61af66fc99e Initial load
duke
parents:
diff changeset
924 void ConcurrentMarkSweepGeneration::reset_after_compaction() {
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // Clear the promotion information. These pointers can be adjusted
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // along with all the other pointers into the heap but
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // compaction is expected to be a rare event with
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // a heap using cms so don't do it without seeing the need.
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
929 if (CollectedHeap::use_parallel_gc_threads()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
930 for (uint i = 0; i < ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
931 _par_gc_thread_states[i]->promo.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
935
a61af66fc99e Initial load
duke
parents:
diff changeset
936 void ConcurrentMarkSweepGeneration::space_iterate(SpaceClosure* blk, bool usedOnly) {
a61af66fc99e Initial load
duke
parents:
diff changeset
937 blk->do_space(_cmsSpace);
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
939
a61af66fc99e Initial load
duke
parents:
diff changeset
940 void ConcurrentMarkSweepGeneration::compute_new_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
941 assert_locked_or_safepoint(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
942
a61af66fc99e Initial load
duke
parents:
diff changeset
943 // If incremental collection failed, we just want to expand
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // to the limit.
a61af66fc99e Initial load
duke
parents:
diff changeset
945 if (incremental_collection_failed()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
946 clear_incremental_collection_failed();
a61af66fc99e Initial load
duke
parents:
diff changeset
947 grow_to_reserved();
a61af66fc99e Initial load
duke
parents:
diff changeset
948 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
950
a61af66fc99e Initial load
duke
parents:
diff changeset
951 size_t expand_bytes = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
952 double free_percentage = ((double) free()) / capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
953 double desired_free_percentage = (double) MinHeapFreeRatio / 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
954 double maximum_free_percentage = (double) MaxHeapFreeRatio / 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956 // compute expansion delta needed for reaching desired free percentage
a61af66fc99e Initial load
duke
parents:
diff changeset
957 if (free_percentage < desired_free_percentage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
958 size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
a61af66fc99e Initial load
duke
parents:
diff changeset
959 assert(desired_capacity >= capacity(), "invalid expansion size");
a61af66fc99e Initial load
duke
parents:
diff changeset
960 expand_bytes = MAX2(desired_capacity - capacity(), MinHeapDeltaBytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
961 }
a61af66fc99e Initial load
duke
parents:
diff changeset
962 if (expand_bytes > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
963 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
964 size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
a61af66fc99e Initial load
duke
parents:
diff changeset
965 gclog_or_tty->print_cr("\nFrom compute_new_size: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
966 gclog_or_tty->print_cr(" Free fraction %f", free_percentage);
a61af66fc99e Initial load
duke
parents:
diff changeset
967 gclog_or_tty->print_cr(" Desired free fraction %f",
a61af66fc99e Initial load
duke
parents:
diff changeset
968 desired_free_percentage);
a61af66fc99e Initial load
duke
parents:
diff changeset
969 gclog_or_tty->print_cr(" Maximum free fraction %f",
a61af66fc99e Initial load
duke
parents:
diff changeset
970 maximum_free_percentage);
a61af66fc99e Initial load
duke
parents:
diff changeset
971 gclog_or_tty->print_cr(" Capactiy "SIZE_FORMAT, capacity()/1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
972 gclog_or_tty->print_cr(" Desired capacity "SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
973 desired_capacity/1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
974 int prev_level = level() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
975 if (prev_level >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
976 size_t prev_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
977 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
978 Generation* prev_gen = gch->_gens[prev_level];
a61af66fc99e Initial load
duke
parents:
diff changeset
979 prev_size = prev_gen->capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
980 gclog_or_tty->print_cr(" Younger gen size "SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
981 prev_size/1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
983 gclog_or_tty->print_cr(" unsafe_max_alloc_nogc "SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
984 unsafe_max_alloc_nogc()/1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
985 gclog_or_tty->print_cr(" contiguous available "SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
986 contiguous_available()/1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
987 gclog_or_tty->print_cr(" Expand by "SIZE_FORMAT" (bytes)",
a61af66fc99e Initial load
duke
parents:
diff changeset
988 expand_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // safe if expansion fails
a61af66fc99e Initial load
duke
parents:
diff changeset
991 expand(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio);
a61af66fc99e Initial load
duke
parents:
diff changeset
992 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
993 gclog_or_tty->print_cr(" Expanded free fraction %f",
a61af66fc99e Initial load
duke
parents:
diff changeset
994 ((double) free()) / capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
998
a61af66fc99e Initial load
duke
parents:
diff changeset
999 Mutex* ConcurrentMarkSweepGeneration::freelistLock() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 return cmsSpace()->freelistLock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 HeapWord* ConcurrentMarkSweepGeneration::allocate(size_t size,
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 bool tlab) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 CMSSynchronousYieldRequest yr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 MutexLockerEx x(freelistLock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 return have_lock_and_allocate(size, tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1010
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 HeapWord* ConcurrentMarkSweepGeneration::have_lock_and_allocate(size_t size,
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1012 bool tlab /* ignored */) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 size_t adjustedSize = CompactibleFreeListSpace::adjustObjectSize(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 HeapWord* res = cmsSpace()->allocate(adjustedSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // Allocate the object live (grey) if the background collector has
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 // started marking. This is necessary because the marker may
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 // have passed this address and consequently this object will
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // not otherwise be greyed and would be incorrectly swept up.
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 // Note that if this object contains references, the writing
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // of those references will dirty the card containing this object
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // allowing the object to be blackened (and its references scanned)
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // either during a preclean phase or at the final checkpoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 if (res != NULL) {
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1025 // We may block here with an uninitialized object with
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1026 // its mark-bit or P-bits not yet set. Such objects need
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1027 // to be safely navigable by block_start().
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1028 assert(oop(res)->klass_or_null() == NULL, "Object should be uninitialized here.");
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1029 assert(!((FreeChunk*)res)->isFree(), "Error, block will look free but show wrong size");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 collector()->direct_allocated(res, adjustedSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 _direct_allocated_words += adjustedSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // allocation counters
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 _numObjectsAllocated++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 _numWordsAllocated += (int)adjustedSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1040
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 // In the case of direct allocation by mutators in a generation that
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 // is being concurrently collected, the object must be allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 // live (grey) if the background collector has started marking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 // This is necessary because the marker may
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 // have passed this address and consequently this object will
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // not otherwise be greyed and would be incorrectly swept up.
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 // Note that if this object contains references, the writing
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 // of those references will dirty the card containing this object
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // allowing the object to be blackened (and its references scanned)
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // either during a preclean phase or at the final checkpoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 void CMSCollector::direct_allocated(HeapWord* start, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 assert(_markBitMap.covers(start, size), "Out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 if (_collectorState >= Marking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 MutexLockerEx y(_markBitMap.lock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 // [see comments preceding SweepClosure::do_blk() below for details]
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // 1. need to mark the object as live so it isn't collected
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 // 2. need to mark the 2nd bit to indicate the object may be uninitialized
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1059 // 3. need to mark the end of the object so marking, precleaning or sweeping
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1060 // can skip over uninitialized or unparsable objects. An allocated
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1061 // object is considered uninitialized for our purposes as long as
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1062 // its klass word is NULL. (Unparsable objects are those which are
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1063 // initialized in the sense just described, but whose sizes can still
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1064 // not be correctly determined. Note that the class of unparsable objects
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1065 // can only occur in the perm gen. All old gen objects are parsable
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1066 // as soon as they are initialized.)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 _markBitMap.mark(start); // object is live
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 _markBitMap.mark(start + 1); // object is potentially uninitialized?
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 _markBitMap.mark(start + size - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 // mark end of object
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 // check that oop looks uninitialized
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
1073 assert(oop(start)->klass_or_null() == NULL, "_klass should be NULL");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 void CMSCollector::promoted(bool par, HeapWord* start,
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 bool is_obj_array, size_t obj_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 assert(_markBitMap.covers(start), "Out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // See comment in direct_allocated() about when objects should
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 // be allocated live.
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 if (_collectorState >= Marking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 // we already hold the marking bit map lock, taken in
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // the prologue
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 if (par) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 _markBitMap.par_mark(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 _markBitMap.mark(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 // We don't need to mark the object as uninitialized (as
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 // in direct_allocated above) because this is being done with the
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // world stopped and the object will be initialized by the
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1092 // time the marking, precleaning or sweeping get to look at it.
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1093 // But see the code for copying objects into the CMS generation,
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1094 // where we need to ensure that concurrent readers of the
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1095 // block offset table are able to safely navigate a block that
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1096 // is in flux from being free to being allocated (and in
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1097 // transition while being copied into) and subsequently
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1098 // becoming a bona-fide object when the copy/promotion is complete.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 assert(SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 "expect promotion only at safepoints");
a61af66fc99e Initial load
duke
parents:
diff changeset
1101
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 if (_collectorState < Sweeping) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 // Mark the appropriate cards in the modUnionTable, so that
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // this object gets scanned before the sweep. If this is
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // not done, CMS generation references in the object might
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 // not get marked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 // For the case of arrays, which are otherwise precisely
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // marked, we need to dirty the entire array, not just its head.
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 if (is_obj_array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // The [par_]mark_range() method expects mr.end() below to
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 // be aligned to the granularity of a bit's representation
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 // in the heap. In the case of the MUT below, that's a
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 // card size.
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 MemRegion mr(start,
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 (HeapWord*)round_to((intptr_t)(start + obj_size),
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 CardTableModRefBS::card_size /* bytes */));
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 if (par) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 _modUnionTable.par_mark_range(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 _modUnionTable.mark_range(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 } else { // not an obj array; we can just mark the head
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 if (par) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 _modUnionTable.par_mark(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 _modUnionTable.mark(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1132
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 static inline size_t percent_of_space(Space* space, HeapWord* addr)
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 size_t delta = pointer_delta(addr, space->bottom());
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 return (size_t)(delta * 100.0 / (space->capacity() / HeapWordSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 void CMSCollector::icms_update_allocation_limits()
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 Generation* gen0 = GenCollectedHeap::heap()->get_gen(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 EdenSpace* eden = gen0->as_DefNewGeneration()->eden();
a61af66fc99e Initial load
duke
parents:
diff changeset
1143
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 const unsigned int duty_cycle = stats().icms_update_duty_cycle();
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 if (CMSTraceIncrementalPacing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 stats().print();
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1148
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 assert(duty_cycle <= 100, "invalid duty cycle");
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 if (duty_cycle != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // The duty_cycle is a percentage between 0 and 100; convert to words and
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // then compute the offset from the endpoints of the space.
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 size_t free_words = eden->free() / HeapWordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 double free_words_dbl = (double)free_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 size_t duty_cycle_words = (size_t)(free_words_dbl * duty_cycle / 100.0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 size_t offset_words = (free_words - duty_cycle_words) / 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1157
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 _icms_start_limit = eden->top() + offset_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 _icms_stop_limit = eden->end() - offset_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // The limits may be adjusted (shifted to the right) by
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // CMSIncrementalOffset, to allow the application more mutator time after a
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 // young gen gc (when all mutators were stopped) and before CMS starts and
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 // takes away one or more cpus.
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 if (CMSIncrementalOffset != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 double adjustment_dbl = free_words_dbl * CMSIncrementalOffset / 100.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 size_t adjustment = (size_t)adjustment_dbl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 HeapWord* tmp_stop = _icms_stop_limit + adjustment;
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 if (tmp_stop > _icms_stop_limit && tmp_stop < eden->end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 _icms_start_limit += adjustment;
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 _icms_stop_limit = tmp_stop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 if (duty_cycle == 0 || (_icms_start_limit == _icms_stop_limit)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 _icms_start_limit = _icms_stop_limit = eden->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1178
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // Install the new start limit.
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 eden->set_soft_end(_icms_start_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 if (CMSTraceIncrementalMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 gclog_or_tty->print(" icms alloc limits: "
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 PTR_FORMAT "," PTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 " (" SIZE_FORMAT "%%," SIZE_FORMAT "%%) ",
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 _icms_start_limit, _icms_stop_limit,
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 percent_of_space(eden, _icms_start_limit),
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 percent_of_space(eden, _icms_stop_limit));
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 gclog_or_tty->print("eden: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 eden->print_on(gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1195
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // Any changes here should try to maintain the invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // that if this method is called with _icms_start_limit
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // and _icms_stop_limit both NULL, then it should return NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // and not notify the icms thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 CMSCollector::allocation_limit_reached(Space* space, HeapWord* top,
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 size_t word_size)
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 // A start_limit equal to end() means the duty cycle is 0, so treat that as a
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 // nop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 if (CMSIncrementalMode && _icms_start_limit != space->end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 if (top <= _icms_start_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 if (CMSTraceIncrementalMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 space->print_on(gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 gclog_or_tty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 gclog_or_tty->print_cr(" start limit top=" PTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 ", new limit=" PTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 " (" SIZE_FORMAT "%%)",
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 top, _icms_stop_limit,
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 percent_of_space(space, _icms_stop_limit));
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 ConcurrentMarkSweepThread::start_icms();
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 assert(top < _icms_stop_limit, "Tautology");
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 if (word_size < pointer_delta(_icms_stop_limit, top)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 return _icms_stop_limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1222
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 // The allocation will cross both the _start and _stop limits, so do the
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 // stop notification also and return end().
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 if (CMSTraceIncrementalMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 space->print_on(gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 gclog_or_tty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 gclog_or_tty->print_cr(" +stop limit top=" PTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 ", new limit=" PTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 " (" SIZE_FORMAT "%%)",
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 top, space->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 percent_of_space(space, space->end()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 ConcurrentMarkSweepThread::stop_icms();
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 return space->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1237
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 if (top <= _icms_stop_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 if (CMSTraceIncrementalMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 space->print_on(gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 gclog_or_tty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 gclog_or_tty->print_cr(" stop limit top=" PTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 ", new limit=" PTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 " (" SIZE_FORMAT "%%)",
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 top, space->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 percent_of_space(space, space->end()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 ConcurrentMarkSweepThread::stop_icms();
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 return space->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1251
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 if (CMSTraceIncrementalMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 space->print_on(gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 gclog_or_tty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 gclog_or_tty->print_cr(" end limit top=" PTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 ", new limit=" PTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 top, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1260
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1263
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
1264 oop ConcurrentMarkSweepGeneration::promote(oop obj, size_t obj_size) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 // allocate, copy and if necessary update promoinfo --
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 // delegate to underlying space.
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
1269
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 if (Universe::heap()->promotion_should_fail()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 #endif // #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1275
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
1276 oop res = _cmsSpace->promote(obj, obj_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 if (res == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 // expand and retry
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 size_t s = _cmsSpace->expansionSpaceRequired(obj_size); // HeapWords
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 expand(s*HeapWordSize, MinHeapDeltaBytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 CMSExpansionCause::_satisfy_promotion);
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // Since there's currently no next generation, we don't try to promote
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // into a more senior generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 assert(next_gen() == NULL, "assumption, based upon which no attempt "
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 "is made to pass on a possibly failing "
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 "promotion to next generation");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
1287 res = _cmsSpace->promote(obj, obj_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 if (res != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 // See comment in allocate() about when objects should
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // be allocated live.
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 assert(obj->is_oop(), "Will dereference klass pointer below");
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 collector()->promoted(false, // Not parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 (HeapWord*)res, obj->is_objArray(), obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // promotion counters
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 _numObjectsPromoted++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 _numWordsPromoted +=
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 (int)(CompactibleFreeListSpace::adjustObjectSize(obj->size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1304
a61af66fc99e Initial load
duke
parents:
diff changeset
1305
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 ConcurrentMarkSweepGeneration::allocation_limit_reached(Space* space,
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 HeapWord* top,
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 size_t word_sz)
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 return collector()->allocation_limit_reached(space, top, word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1313
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1314 // IMPORTANT: Notes on object size recognition in CMS.
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1315 // ---------------------------------------------------
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1316 // A block of storage in the CMS generation is always in
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1317 // one of three states. A free block (FREE), an allocated
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1318 // object (OBJECT) whose size() method reports the correct size,
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1319 // and an intermediate state (TRANSIENT) in which its size cannot
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1320 // be accurately determined.
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1321 // STATE IDENTIFICATION: (32 bit and 64 bit w/o COOPS)
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1322 // -----------------------------------------------------
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1323 // FREE: klass_word & 1 == 1; mark_word holds block size
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1324 //
1777
179464550c7d 6983930: CMS: Various small cleanups ca September 2010
ysr
parents: 1720
diff changeset
1325 // OBJECT: klass_word installed; klass_word != 0 && klass_word & 1 == 0;
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1326 // obj->size() computes correct size
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1327 // [Perm Gen objects needs to be "parsable" before they can be navigated]
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1328 //
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1329 // TRANSIENT: klass_word == 0; size is indeterminate until we become an OBJECT
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1330 //
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1331 // STATE IDENTIFICATION: (64 bit+COOPS)
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1332 // ------------------------------------
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1333 // FREE: mark_word & CMS_FREE_BIT == 1; mark_word & ~CMS_FREE_BIT gives block_size
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1334 //
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1335 // OBJECT: klass_word installed; klass_word != 0;
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1336 // obj->size() computes correct size
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1337 // [Perm Gen comment above continues to hold]
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1338 //
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1339 // TRANSIENT: klass_word == 0; size is indeterminate until we become an OBJECT
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1340 //
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1341 //
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1342 // STATE TRANSITION DIAGRAM
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1343 //
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1344 // mut / parnew mut / parnew
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1345 // FREE --------------------> TRANSIENT ---------------------> OBJECT --|
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1346 // ^ |
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1347 // |------------------------ DEAD <------------------------------------|
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1348 // sweep mut
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1349 //
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1350 // While a block is in TRANSIENT state its size cannot be determined
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1351 // so readers will either need to come back later or stall until
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1352 // the size can be determined. Note that for the case of direct
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1353 // allocation, P-bits, when available, may be used to determine the
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1354 // size of an object that may not yet have been initialized.
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1355
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 // Things to support parallel young-gen collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 oop
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 ConcurrentMarkSweepGeneration::par_promote(int thread_num,
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 oop old, markOop m,
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 size_t word_sz) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 if (Universe::heap()->promotion_should_fail()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 #endif // #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1366
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 PromotionInfo* promoInfo = &ps->promo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 // if we are tracking promotions, then first ensure space for
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 // promotion (including spooling space for saving header if necessary).
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // then allocate and copy, then track promoted info if needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 // When tracking (see PromotionInfo::track()), the mark word may
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 // be displaced and in this case restoration of the mark word
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 // occurs in the (oop_since_save_marks_)iterate phase.
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 if (promoInfo->tracking() && !promoInfo->ensure_spooling_space()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 // Out of space for allocating spooling buffers;
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // try expanding and allocating spooling buffers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 if (!expand_and_ensure_spooling_space(promoInfo)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 assert(promoInfo->has_spooling_space(), "Control point invariant");
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1383 const size_t alloc_sz = CompactibleFreeListSpace::adjustObjectSize(word_sz);
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1384 HeapWord* obj_ptr = ps->lab.alloc(alloc_sz);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 if (obj_ptr == NULL) {
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1386 obj_ptr = expand_and_par_lab_allocate(ps, alloc_sz);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 if (obj_ptr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 oop obj = oop(obj_ptr);
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1392 OrderAccess::storestore();
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
1393 assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1394 assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size");
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1395 // IMPORTANT: See note on object initialization for CMS above.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 // Otherwise, copy the object. Here we must be careful to insert the
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 // klass pointer last, since this marks the block as an allocated object.
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
1398 // Except with compressed oops it's the mark word.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 HeapWord* old_ptr = (HeapWord*)old;
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1400 // Restore the mark word copied above.
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1401 obj->set_mark(m);
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1402 assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1403 assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size");
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1404 OrderAccess::storestore();
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1405
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1406 if (UseCompressedOops) {
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1407 // Copy gap missed by (aligned) header size calculation below
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1408 obj->set_klass_gap(old->klass_gap());
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1409 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 if (word_sz > (size_t)oopDesc::header_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 Copy::aligned_disjoint_words(old_ptr + oopDesc::header_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 obj_ptr + oopDesc::header_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 word_sz - oopDesc::header_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 }
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
1415
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 // Now we can track the promoted object, if necessary. We take care
1521
a8127dc669ba 6951188: CMS: move PromotionInfo into its own file
ysr
parents: 1520
diff changeset
1417 // to delay the transition from uninitialized to full object
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 // (i.e., insertion of klass pointer) until after, so that it
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // atomically becomes a promoted object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 if (promoInfo->tracking()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 promoInfo->track((PromotedObject*)obj, old->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 }
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1423 assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1424 assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size");
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1425 assert(old->is_oop(), "Will use and dereference old klass ptr below");
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
1426
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
1427 // Finally, install the klass pointer (this should be volatile).
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1428 OrderAccess::storestore();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 obj->set_klass(old->klass());
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1430 // We should now be able to calculate the right size for this object
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1431 assert(obj->is_oop() && obj->size() == (int)word_sz, "Error, incorrect size computed for promoted object");
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1432
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 collector()->promoted(true, // parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 obj_ptr, old->is_objArray(), word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1435
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 NOT_PRODUCT(
1716
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1437 Atomic::inc_ptr(&_numObjectsPromoted);
be3f9c242c9d 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 1704
diff changeset
1438 Atomic::add_ptr(alloc_sz, &_numWordsPromoted);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1440
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 return obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1443
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 ConcurrentMarkSweepGeneration::
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 par_promote_alloc_undo(int thread_num,
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 HeapWord* obj, size_t word_sz) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 // CMS does not support promotion undo.
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1451
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 ConcurrentMarkSweepGeneration::
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 par_promote_alloc_done(int thread_num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
1456 ps->lab.retire(thread_num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1458
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 ConcurrentMarkSweepGeneration::
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 par_oop_since_save_marks_iterate_done(int thread_num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 ParScanWithoutBarrierClosure* dummy_cl = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 ps->promo.promoted_oops_iterate_nv(dummy_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1466
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 // XXXPERM
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 bool ConcurrentMarkSweepGeneration::should_collect(bool full,
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 size_t size,
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 bool tlab)
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 // We allow a STW collection only if a full
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 // collection was requested.
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 return full || should_allocate(size, tlab); // FIX ME !!!
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 // This and promotion failure handling are connected at the
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 // hip and should be fixed by untying them.
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1478
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 bool CMSCollector::shouldConcurrentCollect() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 if (_full_gc_requested) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 if (Verbose && PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 gclog_or_tty->print_cr("CMSCollector: collect because of explicit "
1520
bb843ebc7c55 6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents: 1518
diff changeset
1483 " gc request (or gc_locker)");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1487
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // For debugging purposes, change the type of collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 // If the rotation is not on the concurrent collection
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 // type, don't start a concurrent collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 if (RotateCMSCollectionTypes &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 (_cmsGen->debug_collection_type() !=
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 ConcurrentMarkSweepGeneration::Concurrent_collection_type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 assert(_cmsGen->debug_collection_type() !=
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 ConcurrentMarkSweepGeneration::Unknown_collection_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 "Bad cms collection type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1501
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 FreelistLocker x(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 // ------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 // Print out lots of information which affects the initiation of
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // a collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 if (PrintCMSInitiationStatistics && stats().valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 gclog_or_tty->print("CMSCollector shouldConcurrentCollect: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 gclog_or_tty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 gclog_or_tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 stats().print_on(gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f",
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 stats().time_until_cms_gen_full());
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 gclog_or_tty->print_cr("free="SIZE_FORMAT, _cmsGen->free());
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 gclog_or_tty->print_cr("contiguous_available="SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 _cmsGen->contiguous_available());
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 gclog_or_tty->print_cr("promotion_rate=%g", stats().promotion_rate());
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 gclog_or_tty->print_cr("cms_allocation_rate=%g", stats().cms_allocation_rate());
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 gclog_or_tty->print_cr("occupancy=%3.7f", _cmsGen->occupancy());
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1519 gclog_or_tty->print_cr("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy());
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1520 gclog_or_tty->print_cr("initiatingPermOccupancy=%3.7f", _permGen->initiating_occupancy());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 // ------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1523
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // If the estimated time to complete a cms collection (cms_duration())
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 // is less than the estimated time remaining until the cms generation
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 // is full, start a collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 if (!UseCMSInitiatingOccupancyOnly) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 if (stats().valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 if (stats().time_until_cms_start() == 0.0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 // We want to conservatively collect somewhat early in order
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 // to try and "bootstrap" our CMS/promotion statistics;
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // this branch will not fire after the first successful CMS
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 // collection because the stats should then be valid.
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 if (_cmsGen->occupancy() >= _bootstrap_occupancy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 if (Verbose && PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 gclog_or_tty->print_cr(
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 " CMSCollector: collect for bootstrapping statistics:"
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 " occupancy = %f, boot occupancy = %f", _cmsGen->occupancy(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 _bootstrap_occupancy);
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1548
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 // Otherwise, we start a collection cycle if either the perm gen or
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 // old gen want a collection cycle started. Each may use
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 // an appropriate criterion for making this decision.
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 // XXX We need to make sure that the gen expansion
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1553 // criterion dovetails well with this. XXX NEED TO FIX THIS
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1554 if (_cmsGen->should_concurrent_collect()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 if (Verbose && PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 gclog_or_tty->print_cr("CMS old gen initiated");
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1560
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1561 // We start a collection if we believe an incremental collection may fail;
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1562 // this is not likely to be productive in practice because it's probably too
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1563 // late anyway.
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1564 GenCollectedHeap* gch = GenCollectedHeap::heap();
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1565 assert(gch->collector_policy()->is_two_generation_policy(),
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1566 "You may want to check the correctness of the following");
1994
6cd6d394f280 7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
ysr
parents: 1972
diff changeset
1567 if (gch->incremental_collection_will_fail(true /* consult_young */)) {
6cd6d394f280 7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
ysr
parents: 1972
diff changeset
1568 if (Verbose && PrintGCDetails) {
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1569 gclog_or_tty->print("CMSCollector: collect because incremental collection will fail ");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1573
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1574 if (CMSClassUnloadingEnabled && _permGen->should_concurrent_collect()) {
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1575 bool res = update_should_unload_classes();
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1576 if (res) {
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1577 if (Verbose && PrintGCDetails) {
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1578 gclog_or_tty->print_cr("CMS perm gen initiated");
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1579 }
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1580 return true;
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1581 }
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1582 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1585
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 // Clear _expansion_cause fields of constituent generations
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 void CMSCollector::clear_expansion_cause() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 _cmsGen->clear_expansion_cause();
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 _permGen->clear_expansion_cause();
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1591
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1592 // We should be conservative in starting a collection cycle. To
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1593 // start too eagerly runs the risk of collecting too often in the
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1594 // extreme. To collect too rarely falls back on full collections,
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1595 // which works, even if not optimum in terms of concurrent work.
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1596 // As a work around for too eagerly collecting, use the flag
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1597 // UseCMSInitiatingOccupancyOnly. This also has the advantage of
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1598 // giving the user an easily understandable way of controlling the
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1599 // collections.
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1600 // We want to start a new collection cycle if any of the following
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1601 // conditions hold:
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1602 // . our current occupancy exceeds the configured initiating occupancy
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1603 // for this generation, or
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1604 // . we recently needed to expand this space and have not, since that
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1605 // expansion, done a collection of this generation, or
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1606 // . the underlying space believes that it may be a good idea to initiate
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1607 // a concurrent collection (this may be based on criteria such as the
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1608 // following: the space uses linear allocation and linear allocation is
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1609 // going to fail, or there is believed to be excessive fragmentation in
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1610 // the generation, etc... or ...
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1611 // [.(currently done by CMSCollector::shouldConcurrentCollect() only for
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1612 // the case of the old generation, not the perm generation; see CR 6543076):
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1613 // we may be approaching a point at which allocation requests may fail because
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1614 // we will be out of sufficient free space given allocation rate estimates.]
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1615 bool ConcurrentMarkSweepGeneration::should_concurrent_collect() const {
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1616
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 assert_lock_strong(freelistLock());
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1618 if (occupancy() > initiating_occupancy()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 gclog_or_tty->print(" %s: collect because of occupancy %f / %f ",
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1621 short_name(), occupancy(), initiating_occupancy());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 if (UseCMSInitiatingOccupancyOnly) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 if (expansion_cause() == CMSExpansionCause::_satisfy_allocation) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 gclog_or_tty->print(" %s: collect because expanded for allocation ",
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 short_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 }
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1635 if (_cmsSpace->should_concurrent_collect()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 if (PrintGCDetails && Verbose) {
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
1637 gclog_or_tty->print(" %s: collect because cmsSpace says so ",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 short_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 void ConcurrentMarkSweepGeneration::collect(bool full,
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 bool clear_all_soft_refs,
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 size_t size,
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 bool tlab)
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 collector()->collect(full, clear_all_soft_refs, size, tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1652
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 void CMSCollector::collect(bool full,
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 bool clear_all_soft_refs,
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 size_t size,
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 bool tlab)
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 if (!UseCMSCollectionPassing && _collectorState > Idling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 // For debugging purposes skip the collection if the state
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 // is not currently idle
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " skipped full:%d CMS state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 Thread::current(), full, _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1667
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 // The following "if" branch is present for defensive reasons.
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 // In the current uses of this interface, it can be replaced with:
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 // assert(!GC_locker.is_active(), "Can't be called otherwise");
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 // But I am not placing that assert here to allow future
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 // generality in invoking this interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 if (GC_locker::is_active()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 // A consistency test for GC_locker
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 assert(GC_locker::needs_gc(), "Should have been set already");
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 // Skip this foreground collection, instead
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 // expanding the heap if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 // Need the free list locks for the call to free() in compute_new_size()
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 compute_new_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 acquire_control_and_collect(full, clear_all_soft_refs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 _full_gcs_since_conc_gc++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1684
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1686
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 void CMSCollector::request_full_gc(unsigned int full_gc_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 unsigned int gc_count = gch->total_full_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 if (gc_count == full_gc_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 _full_gc_requested = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 CGC_lock->notify(); // nudge CMS thread
2365
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 2226
diff changeset
1694 } else {
a181f3a124dd 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 2226
diff changeset
1695 assert(gc_count > full_gc_count, "Error: causal loop");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1698
a61af66fc99e Initial load
duke
parents:
diff changeset
1699
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 // The foreground and background collectors need to coordinate in order
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 // to make sure that they do not mutually interfere with CMS collections.
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 // When a background collection is active,
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // the foreground collector may need to take over (preempt) and
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // synchronously complete an ongoing collection. Depending on the
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 // frequency of the background collections and the heap usage
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 // of the application, this preemption can be seldom or frequent.
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 // There are only certain
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 // points in the background collection that the "collection-baton"
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 // can be passed to the foreground collector.
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 // The foreground collector will wait for the baton before
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 // starting any part of the collection. The foreground collector
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 // will only wait at one location.
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 // The background collector will yield the baton before starting a new
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 // phase of the collection (e.g., before initial marking, marking from roots,
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 // precleaning, final re-mark, sweep etc.) This is normally done at the head
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 // of the loop which switches the phases. The background collector does some
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 // of the phases (initial mark, final re-mark) with the world stopped.
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 // Because of locking involved in stopping the world,
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 // the foreground collector should not block waiting for the background
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 // collector when it is doing a stop-the-world phase. The background
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 // collector will yield the baton at an additional point just before
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // it enters a stop-the-world phase. Once the world is stopped, the
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // background collector checks the phase of the collection. If the
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 // phase has not changed, it proceeds with the collection. If the
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 // phase has changed, it skips that phase of the collection. See
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 // the comments on the use of the Heap_lock in collect_in_background().
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 // Variable used in baton passing.
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 // _foregroundGCIsActive - Set to true by the foreground collector when
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 // it wants the baton. The foreground clears it when it has finished
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // the collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 // _foregroundGCShouldWait - Set to true by the background collector
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 // when it is running. The foreground collector waits while
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 // _foregroundGCShouldWait is true.
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 // CGC_lock - monitor used to protect access to the above variables
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // and to notify the foreground and background collectors.
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 // _collectorState - current state of the CMS collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 // The foreground collector
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 // acquires the CGC_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 // sets _foregroundGCIsActive
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 // waits on the CGC_lock for _foregroundGCShouldWait to be false
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 // various locks acquired in preparation for the collection
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 // are released so as not to block the background collector
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 // that is in the midst of a collection
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 // proceeds with the collection
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 // clears _foregroundGCIsActive
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // returns
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 // The background collector in a loop iterating on the phases of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 // collection
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 // acquires the CGC_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 // sets _foregroundGCShouldWait
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 // if _foregroundGCIsActive is set
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 // clears _foregroundGCShouldWait, notifies _CGC_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 // waits on _CGC_lock for _foregroundGCIsActive to become false
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 // and exits the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 // otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 // proceed with that phase of the collection
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 // if the phase is a stop-the-world phase,
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 // yield the baton once more just before enqueueing
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 // the stop-world CMS operation (executed by the VM thread).
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 // returns after all phases of the collection are done
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1767
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 void CMSCollector::acquire_control_and_collect(bool full,
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 bool clear_all_soft_refs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 assert(!Thread::current()->is_ConcurrentGC_thread(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 "shouldn't try to acquire control from self!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1773
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 // Start the protocol for acquiring control of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 // collection from the background collector (aka CMS thread).
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 "VM thread should have CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 // Remember the possibly interrupted state of an ongoing
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 // concurrent collection
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 CollectorState first_state = _collectorState;
a61af66fc99e Initial load
duke
parents:
diff changeset
1781
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 // Signal to a possibly ongoing concurrent collection that
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 // we want to do a foreground collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 _foregroundGCIsActive = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1785
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 // Disable incremental mode during a foreground collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 ICMSDisabler icms_disabler;
a61af66fc99e Initial load
duke
parents:
diff changeset
1788
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 // release locks and wait for a notify from the background collector
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 // releasing the locks in only necessary for phases which
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 // do yields to improve the granularity of the collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 // We need to lock the Free list lock for the space that we are
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // currently collecting.
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 assert(haveFreelistLocks(), "Must be holding free list locks");
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 bitMapLock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 releaseFreelistLocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 if (_foregroundGCShouldWait) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 // We are going to be waiting for action for the CMS thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 // it had better not be gone (for instance at shutdown)!
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 assert(ConcurrentMarkSweepThread::cmst() != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 "CMS thread must be running");
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 // Wait here until the background collector gives us the go-ahead
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 ConcurrentMarkSweepThread::clear_CMS_flag(
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 ConcurrentMarkSweepThread::CMS_vm_has_token); // release token
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 // Get a possibly blocked CMS thread going:
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 // Note that we set _foregroundGCIsActive true above,
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // without protection of the CGC_lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 CGC_lock->notify();
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 assert(!ConcurrentMarkSweepThread::vm_thread_wants_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 "Possible deadlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 while (_foregroundGCShouldWait) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 // wait for notification
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 CGC_lock->wait(Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 // Possibility of delay/starvation here, since CMS token does
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 // not know to give priority to VM thread? Actually, i think
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 // there wouldn't be any delay/starvation, but the proof of
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 // that "fact" (?) appears non-trivial. XXX 20011219YSR
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 ConcurrentMarkSweepThread::set_CMS_flag(
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 ConcurrentMarkSweepThread::CMS_vm_has_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 // The CMS_token is already held. Get back the other locks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 "VM thread should have CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 getFreelistLocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 bitMapLock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 gclog_or_tty->print_cr("CMS foreground collector has asked for control "
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 INTPTR_FORMAT " with first state %d", Thread::current(), first_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 gclog_or_tty->print_cr(" gets control with state %d", _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1836
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 // Check if we need to do a compaction, or if not, whether
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 // we need to start the mark-sweep from scratch.
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 bool should_compact = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 bool should_start_over = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 decide_foreground_collection_type(clear_all_soft_refs,
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 &should_compact, &should_start_over);
a61af66fc99e Initial load
duke
parents:
diff changeset
1843
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 if (RotateCMSCollectionTypes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 if (_cmsGen->debug_collection_type() ==
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 ConcurrentMarkSweepGeneration::MSC_foreground_collection_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 should_compact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 } else if (_cmsGen->debug_collection_type() ==
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 ConcurrentMarkSweepGeneration::MS_foreground_collection_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 should_compact = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1855
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 if (PrintGCDetails && first_state > Idling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause();
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 if (GCCause::is_user_requested_gc(cause) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 GCCause::is_serviceability_requested_gc(cause)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 gclog_or_tty->print(" (concurrent mode interrupted)");
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 gclog_or_tty->print(" (concurrent mode failure)");
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1865
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 if (should_compact) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 // If the collection is being acquired from the background
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 // collector, there may be references on the discovered
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 // references lists that have NULL referents (being those
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 // that were concurrently cleared by a mutator) or
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 // that are no longer active (having been enqueued concurrently
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 // by the mutator).
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 // Scrub the list of those references because Mark-Sweep-Compact
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 // code assumes referents are not NULL and that all discovered
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 // Reference objects are active.
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 ref_processor()->clean_up_discovered_references();
a61af66fc99e Initial load
duke
parents:
diff changeset
1877
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 do_compaction_work(clear_all_soft_refs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1879
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 // Has the GC time limit been exceeded?
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1881 DefNewGeneration* young_gen = _young_gen->as_DefNewGeneration();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1882 size_t max_eden_size = young_gen->max_capacity() -
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1883 young_gen->to()->capacity() -
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1884 young_gen->from()->capacity();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1885 GenCollectedHeap* gch = GenCollectedHeap::heap();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1886 GCCause::Cause gc_cause = gch->gc_cause();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1887 size_policy()->check_gc_overhead_limit(_young_gen->used(),
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1888 young_gen->eden()->used(),
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1889 _cmsGen->max_capacity(),
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1890 max_eden_size,
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1891 full,
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1892 gc_cause,
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
1893 gch->collector_policy());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 do_mark_sweep_work(clear_all_soft_refs, first_state,
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 should_start_over);
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 // Reset the expansion cause, now that we just completed
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 // a collection cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 clear_expansion_cause();
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 _foregroundGCIsActive = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1904
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 // Resize the perm generation and the tenured generation
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 // after obtaining the free list locks for the
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 // two generations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 void CMSCollector::compute_new_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 assert_locked_or_safepoint(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 FreelistLocker z(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 _permGen->compute_new_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 _cmsGen->compute_new_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1914
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 // A work method used by foreground collection to determine
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 // what type of collection (compacting or not, continuing or fresh)
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 // it should do.
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 // NOTE: the intent is to make UseCMSCompactAtFullCollection
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 // and CMSCompactWhenClearAllSoftRefs the default in the future
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 // and do away with the flags after a suitable period.
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 void CMSCollector::decide_foreground_collection_type(
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 bool clear_all_soft_refs, bool* should_compact,
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 bool* should_start_over) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 // Normally, we'll compact only if the UseCMSCompactAtFullCollection
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 // flag is set, and we have either requested a System.gc() or
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 // the number of full gc's since the last concurrent cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 // has exceeded the threshold set by CMSFullGCsBeforeCompaction,
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 // or if an incremental collection has failed
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 assert(gch->collector_policy()->is_two_generation_policy(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 "You may want to check the correctness of the following");
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 // Inform cms gen if this was due to partial collection failing.
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // The CMS gen may use this fact to determine its expansion policy.
1994
6cd6d394f280 7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
ysr
parents: 1972
diff changeset
1934 if (gch->incremental_collection_will_fail(false /* don't consult_young */)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 assert(!_cmsGen->incremental_collection_failed(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 "Should have been noticed, reacted to and cleared");
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 _cmsGen->set_incremental_collection_failed();
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 *should_compact =
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 UseCMSCompactAtFullCollection &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 ((_full_gcs_since_conc_gc >= CMSFullGCsBeforeCompaction) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 GCCause::is_user_requested_gc(gch->gc_cause()) ||
1994
6cd6d394f280 7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
ysr
parents: 1972
diff changeset
1943 gch->incremental_collection_will_fail(true /* consult_young */));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 *should_start_over = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 if (clear_all_soft_refs && !*should_compact) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 // We are about to do a last ditch collection attempt
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 // so it would normally make sense to do a compaction
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 // to reclaim as much space as possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 if (CMSCompactWhenClearAllSoftRefs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 // Default: The rationale is that in this case either
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 // we are past the final marking phase, in which case
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 // we'd have to start over, or so little has been done
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 // that there's little point in saving that work. Compaction
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 // appears to be the sensible choice in either case.
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 *should_compact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // We have been asked to clear all soft refs, but not to
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // compact. Make sure that we aren't past the final checkpoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 // phase, for that is where we process soft refs. If we are already
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 // past that phase, we'll need to redo the refs discovery phase and
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 // if necessary clear soft refs that weren't previously
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 // cleared. We do so by remembering the phase in which
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 // we came in, and if we are past the refs processing
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 // phase, we'll choose to just redo the mark-sweep
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 // collection from scratch.
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 if (_collectorState > FinalMarking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 // We are past the refs processing phase;
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 // start over and do a fresh synchronous CMS cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 _collectorState = Resetting; // skip to reset to start new cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 reset(false /* == !asynch */);
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 *should_start_over = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 } // else we can continue a possibly ongoing current cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1976
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 // A work method used by the foreground collector to do
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 // a mark-sweep-compact.
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 TraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 if (PrintGC && Verbose && !(GCCause::is_user_requested_gc(gch->gc_cause()))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 gclog_or_tty->print_cr("Compact ConcurrentMarkSweepGeneration after %d "
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 "collections passed to foreground collector", _full_gcs_since_conc_gc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1986
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 // Sample collection interval time and reset for collection pause.
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 size_policy()->msc_collection_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1991
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 // Temporarily widen the span of the weak reference processing to
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 // the entire heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 MemRegion new_span(GenCollectedHeap::heap()->reserved_region());
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
1995 ReferenceProcessorSpanMutator rp_mut_span(ref_processor(), new_span);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 // Temporarily, clear the "is_alive_non_header" field of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 // reference processor.
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
1998 ReferenceProcessorIsAliveMutator rp_mut_closure(ref_processor(), NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 // Temporarily make reference _processing_ single threaded (non-MT).
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
2000 ReferenceProcessorMTProcMutator rp_mut_mt_processing(ref_processor(), false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 // Temporarily make refs discovery atomic
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
2002 ReferenceProcessorAtomicMutator rp_mut_atomic(ref_processor(), true);
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
2003 // Temporarily make reference _discovery_ single threaded (non-MT)
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
2004 ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2005
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 ref_processor()->set_enqueuing_is_done(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 ref_processor()->enable_discovery();
457
27a80744a83b 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 453
diff changeset
2008 ref_processor()->setup_policy(clear_all_soft_refs);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // If an asynchronous collection finishes, the _modUnionTable is
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 // all clear. If we are assuming the collection from an asynchronous
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 // collection, clear the _modUnionTable.
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 assert(_collectorState != Idling || _modUnionTable.isAllClear(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 "_modUnionTable should be clear if the baton was not passed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 _modUnionTable.clear_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2015
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 // We must adjust the allocation statistics being maintained
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 // in the free list space. We do so by reading and clearing
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 // the sweep timer and updating the block flux rate estimates below.
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2019 assert(!_intra_sweep_timer.is_active(), "_intra_sweep_timer should be inactive");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2020 if (_inter_sweep_timer.is_active()) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2021 _inter_sweep_timer.stop();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2022 // Note that we do not use this sample to update the _inter_sweep_estimate.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2023 _cmsGen->cmsSpace()->beginSweepFLCensus((float)(_inter_sweep_timer.seconds()),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2024 _inter_sweep_estimate.padded_average(),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2025 _intra_sweep_estimate.padded_average());
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2026 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2027
1703
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
2028 {
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
2029 TraceCMSMemoryManagerStats();
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
2030 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 GenMarkSweep::invoke_at_safepoint(_cmsGen->level(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 ref_processor(), clear_all_soft_refs);
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 size_t free_size = cms_space->free();
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 assert(free_size ==
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 pointer_delta(cms_space->end(), cms_space->compaction_top())
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 * HeapWordSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 "All the free space should be compacted into one chunk at top");
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 assert(cms_space->dictionary()->totalChunkSize(
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 debug_only(cms_space->freelistLock())) == 0 ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 cms_space->totalSizeInIndexedFreeLists() == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 "All the free space should be in a single chunk");
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 size_t num = cms_space->totalCount();
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 assert((free_size == 0 && num == 0) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 (free_size > 0 && (num == 1 || num == 2)),
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 "There should be at most 2 free chunks after compaction");
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 _collectorState = Resetting;
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 assert(_restart_addr == NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 "Should have been NULL'd before baton was passed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 reset(false /* == !asynch */);
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 _cmsGen->reset_after_compaction();
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
2054 _concurrent_cycles_since_last_unload = 0;
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
2055
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
2056 if (verifying() && !should_unload_classes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 perm_gen_verify_bit_map()->clear_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2059
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 // Clear any data recorded in the PLAB chunk arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 if (_survivor_plab_array != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 reset_survivor_plab_arrays();
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2064
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 // Adjust the per-size allocation stats for the next epoch.
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2066 _cmsGen->cmsSpace()->endSweepFLCensus(sweep_count() /* fake */);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2067 // Restart the "inter sweep timer" for the next epoch.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2068 _inter_sweep_timer.reset();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2069 _inter_sweep_timer.start();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2070
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 // Sample collection pause time and reset for collection interval.
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 size_policy()->msc_collection_end(gch->gc_cause());
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2075
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 // For a mark-sweep-compact, compute_new_size() will be called
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 // in the heap's do_collection() method.
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2079
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 // A work method used by the foreground collector to do
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 // a mark-sweep, after taking over from a possibly on-going
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // concurrent mark-sweep collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 CollectorState first_state, bool should_start_over) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 if (PrintGC && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 gclog_or_tty->print_cr("Pass concurrent collection to foreground "
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 "collector with count %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 _full_gcs_since_conc_gc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 switch (_collectorState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 case Idling:
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 if (first_state == Idling || should_start_over) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 // The background GC was not active, or should
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 // restarted from scratch; start the cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 _collectorState = InitialMarking;
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 // If first_state was not Idling, then a background GC
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 // was in progress and has now finished. No need to do it
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 // again. Leave the state as Idling.
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 case Precleaning:
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 // In the foreground case don't do the precleaning since
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 // it is not done concurrently and there is extra work
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 // required.
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 _collectorState = FinalMarking;
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 if (PrintGCDetails &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 (_collectorState > Idling ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 !GCCause::is_user_requested_gc(GenCollectedHeap::heap()->gc_cause()))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 gclog_or_tty->print(" (concurrent mode failure)");
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 collect_in_foreground(clear_all_soft_refs);
a61af66fc99e Initial load
duke
parents:
diff changeset
2113
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 // For a mark-sweep, compute_new_size() will be called
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 // in the heap's do_collection() method.
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2117
a61af66fc99e Initial load
duke
parents:
diff changeset
2118
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 void CMSCollector::getFreelistLocks() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 // Get locks for all free lists in all generations that this
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 // collector is responsible for
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 _cmsGen->freelistLock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 _permGen->freelistLock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2125
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 void CMSCollector::releaseFreelistLocks() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 // Release locks for all free lists in all generations that this
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 // collector is responsible for
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 _cmsGen->freelistLock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 _permGen->freelistLock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 bool CMSCollector::haveFreelistLocks() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 // Check locks for all free lists in all generations that this
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 // collector is responsible for
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 assert_lock_strong(_cmsGen->freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 assert_lock_strong(_permGen->freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 PRODUCT_ONLY(ShouldNotReachHere());
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2141
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 // A utility class that is used by the CMS collector to
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 // temporarily "release" the foreground collector from its
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 // usual obligation to wait for the background collector to
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 // complete an ongoing phase before proceeding.
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 class ReleaseForegroundGC: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 CMSCollector* _c;
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 ReleaseForegroundGC(CMSCollector* c) : _c(c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 assert(_c->_foregroundGCShouldWait, "Else should not need to call");
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 // allow a potentially blocked foreground collector to proceed
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 _c->_foregroundGCShouldWait = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 if (_c->_foregroundGCIsActive) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 CGC_lock->notify();
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 "Possible deadlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2161
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 ~ReleaseForegroundGC() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 assert(!_c->_foregroundGCShouldWait, "Usage protocol violation?");
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 _c->_foregroundGCShouldWait = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2168
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 // There are separate collect_in_background and collect_in_foreground because of
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 // the different locking requirements of the background collector and the
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 // foreground collector. There was originally an attempt to share
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // one "collect" method between the background collector and the foreground
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // collector but the if-then-else required made it cleaner to have
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 // separate methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 assert(Thread::current()->is_ConcurrentGC_thread(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 "A CMS asynchronous collection is only allowed on a CMS thread.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2178
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 bool safepoint_check = Mutex::_no_safepoint_check_flag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 MutexLockerEx hl(Heap_lock, safepoint_check);
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
2183 FreelistLocker fll(this);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 MutexLockerEx x(CGC_lock, safepoint_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 if (_foregroundGCIsActive || !UseAsyncConcMarkSweepGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 // The foreground collector is active or we're
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 // not using asynchronous collections. Skip this
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 // background collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 assert(!_foregroundGCShouldWait, "Should be clear");
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 assert(_collectorState == Idling, "Should be idling before start.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 _collectorState = InitialMarking;
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 // Reset the expansion cause, now that we are about to begin
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 // a new cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 clear_expansion_cause();
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 }
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
2198 // Decide if we want to enable class unloading as part of the
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
2199 // ensuing concurrent GC cycle.
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
2200 update_should_unload_classes();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 _full_gc_requested = false; // acks all outstanding full gc requests
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 // Signal that we are about to start a collection
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 gch->increment_total_full_collections(); // ... starting a collection cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 _collection_count_start = gch->total_full_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2206
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 // Used for PrintGC
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 size_t prev_used;
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 if (PrintGC && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 prev_used = _cmsGen->used(); // XXXPERM
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2212
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 // The change of the collection state is normally done at this level;
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 // the exceptions are phases that are executed while the world is
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 // stopped. For those phases the change of state is done while the
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 // world is stopped. For baton passing purposes this allows the
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 // background collector to finish the phase and change state atomically.
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 // The foreground collector cannot wait on a phase that is done
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 // while the world is stopped because the foreground collector already
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 // has the world stopped and would deadlock.
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 while (_collectorState != Idling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 Thread::current(), _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 // The foreground collector
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 // holds the Heap_lock throughout its collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 // holds the CMS token (but not the lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 // except while it is waiting for the background collector to yield.
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 // The foreground collector should be blocked (not for long)
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 // if the background collector is about to start a phase
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 // executed with world stopped. If the background
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 // collector has already started such a phase, the
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 // foreground collector is blocked waiting for the
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 // Heap_lock. The stop-world phases (InitialMarking and FinalMarking)
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 // are executed in the VM thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 // The locking order is
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 // PendingListLock (PLL) -- if applicable (FinalMarking)
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 // Heap_lock (both this & PLL locked in VM_CMS_Operation::prologue())
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 // CMS token (claimed in
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 // stop_world_and_do() -->
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 // safepoint_synchronize() -->
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 // CMSThread::synchronize())
a61af66fc99e Initial load
duke
parents:
diff changeset
2246
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 // Check if the FG collector wants us to yield.
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 CMSTokenSync x(true); // is cms thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 if (waitForForegroundGC()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 // We yielded to a foreground GC, nothing more to be
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 // done this round.
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 assert(_foregroundGCShouldWait == false, "We set it to false in "
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 "waitForForegroundGC()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 " exiting collection CMS state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 Thread::current(), _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 // The background collector can run but check to see if the
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 // foreground collector has done a collection while the
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 // background collector was waiting to get the CGC_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 // above. If yes, break so that _foregroundGCShouldWait
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 // is cleared before returning.
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 if (_collectorState == Idling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2272
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 assert(_foregroundGCShouldWait, "Foreground collector, if active, "
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 "should be waiting");
a61af66fc99e Initial load
duke
parents:
diff changeset
2275
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 switch (_collectorState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 case InitialMarking:
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 ReleaseForegroundGC x(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 stats().record_cms_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
2281
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 VM_CMS_Initial_Mark initial_mark_op(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 VMThread::execute(&initial_mark_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 // The collector state may be any legal state at this point
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 // since the background collector may have yielded to the
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 // foreground collector.
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 case Marking:
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 // initial marking in checkpointRootsInitialWork has been completed
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 if (markFromRoots(true)) { // we were successful
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 assert(_collectorState == Precleaning, "Collector state should "
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 "have changed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 assert(_foregroundGCIsActive, "Internal state inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 case Precleaning:
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 size_policy()->concurrent_precleaning_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 // marking from roots in markFromRoots has been completed
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 preclean();
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 size_policy()->concurrent_precleaning_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 assert(_collectorState == AbortablePreclean ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 _collectorState == FinalMarking,
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 "Collector state should have changed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 case AbortablePreclean:
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 size_policy()->concurrent_phases_resume();
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 abortable_preclean();
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 size_policy()->concurrent_precleaning_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 assert(_collectorState == FinalMarking, "Collector state should "
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 "have changed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 case FinalMarking:
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 ReleaseForegroundGC x(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2325
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 VM_CMS_Final_Remark final_remark_op(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 VMThread::execute(&final_remark_op);
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
2328 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 assert(_foregroundGCShouldWait, "block post-condition");
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 case Sweeping:
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 size_policy()->concurrent_sweeping_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 // final marking in checkpointRootsFinal has been completed
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 sweep(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 assert(_collectorState == Resizing, "Collector state change "
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 "to Resizing must be done under the free_list_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 _full_gcs_since_conc_gc = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2340
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 // Stop the timers for adaptive size policy for the concurrent phases
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 size_policy()->concurrent_sweeping_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 size_policy()->concurrent_phases_end(gch->gc_cause(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 gch->prev_gen(_cmsGen)->capacity(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 _cmsGen->free());
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2348
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 case Resizing: {
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 // Sweeping has been completed...
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 // At this point the background collection has completed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 // Don't move the call to compute_new_size() down
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 // into code that might be executed if the background
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 // collection was preempted.
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 ReleaseForegroundGC x(this); // unblock FG collection
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 MutexLockerEx y(Heap_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 CMSTokenSync z(true); // not strictly needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 if (_collectorState == Resizing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 compute_new_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 _collectorState = Resetting;
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 assert(_collectorState == Idling, "The state should only change"
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 " because the foreground collector has finished the collection");
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 case Resetting:
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 // CMS heap resizing has been completed
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 reset(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 assert(_collectorState == Idling, "Collector state should "
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 "have changed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 stats().record_cms_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 // Don't move the concurrent_phases_end() and compute_new_size()
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 // calls to here because a preempted background collection
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 // has it's state set to "Resetting".
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 case Idling:
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 gclog_or_tty->print_cr(" Thread " INTPTR_FORMAT " done - next CMS state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 Thread::current(), _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 assert(_foregroundGCShouldWait, "block post-condition");
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2390
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 // Should this be in gc_epilogue?
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 collector_policy()->counters()->update_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
2393
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 // Clear _foregroundGCShouldWait and, in the event that the
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 // foreground collector is waiting, notify it, before
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 // returning.
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 _foregroundGCShouldWait = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 if (_foregroundGCIsActive) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 CGC_lock->notify();
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 "Possible deadlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 " exiting collection CMS state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 Thread::current(), _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 if (PrintGC && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 _cmsGen->print_heap_change(prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2415
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 assert(_foregroundGCIsActive && !_foregroundGCShouldWait,
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 "Foreground collector should be waiting, not executing");
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 assert(Thread::current()->is_VM_thread(), "A foreground collection"
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 "may only be done by the VM Thread with the world stopped");
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 "VM thread should have CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
2423
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 NOT_PRODUCT(TraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 true, gclog_or_tty);)
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 size_policy()->ms_collection_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact);
a61af66fc99e Initial load
duke
parents:
diff changeset
2430
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 HandleMark hm; // Discard invalid handles created during verification
a61af66fc99e Initial load
duke
parents:
diff changeset
2432
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 if (VerifyBeforeGC &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2437
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
2438 // Snapshot the soft reference policy to be used in this collection cycle.
457
27a80744a83b 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 453
diff changeset
2439 ref_processor()->setup_policy(clear_all_soft_refs);
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
2440
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 bool init_mark_was_synchronous = false; // until proven otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 while (_collectorState != Idling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 Thread::current(), _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 switch (_collectorState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 case InitialMarking:
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 init_mark_was_synchronous = true; // fact to be exploited in re-mark
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 checkpointRootsInitial(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 assert(_collectorState == Marking, "Collector state should have changed"
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 " within checkpointRootsInitial()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 case Marking:
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 // initial marking in checkpointRootsInitialWork has been completed
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 if (VerifyDuringGC &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 gclog_or_tty->print("Verify before initial mark: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 bool res = markFromRoots(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 assert(res && _collectorState == FinalMarking, "Collector state should "
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 "have changed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 case FinalMarking:
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 if (VerifyDuringGC &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 gclog_or_tty->print("Verify before re-mark: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 checkpointRootsFinal(false, clear_all_soft_refs,
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 init_mark_was_synchronous);
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 assert(_collectorState == Sweeping, "Collector state should not "
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 "have changed within checkpointRootsFinal()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 case Sweeping:
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 // final marking in checkpointRootsFinal has been completed
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 if (VerifyDuringGC &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 gclog_or_tty->print("Verify before sweep: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 sweep(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 assert(_collectorState == Resizing, "Incorrect state");
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 case Resizing: {
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 // Sweeping has been completed; the actual resize in this case
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 // is done separately; nothing to be done in this state.
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 _collectorState = Resetting;
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 case Resetting:
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 // The heap has been resized.
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 if (VerifyDuringGC &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 gclog_or_tty->print("Verify before reset: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 reset(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 assert(_collectorState == Idling, "Collector state should "
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 "have changed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 case Precleaning:
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 case AbortablePreclean:
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 // Elide the preclean phase
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 _collectorState = FinalMarking;
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 gclog_or_tty->print_cr(" Thread " INTPTR_FORMAT " done - next CMS state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 Thread::current(), _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2518
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 size_policy()->ms_collection_end(gch->gc_cause());
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2523
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 if (VerifyAfterGC &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 " exiting collection CMS state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 Thread::current(), _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2534
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 bool CMSCollector::waitForForegroundGC() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 bool res = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 "CMS thread should have CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 // Block the foreground collector until the
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 // background collectors decides whether to
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 // yield.
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 _foregroundGCShouldWait = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 if (_foregroundGCIsActive) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 // The background collector yields to the
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 // foreground collector and returns a value
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 // indicating that it has yielded. The foreground
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 // collector can proceed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 res = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 _foregroundGCShouldWait = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 ConcurrentMarkSweepThread::clear_CMS_flag(
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 ConcurrentMarkSweepThread::CMS_cms_has_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 ConcurrentMarkSweepThread::set_CMS_flag(
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 ConcurrentMarkSweepThread::CMS_cms_wants_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 // Get a possibly blocked foreground thread going
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 CGC_lock->notify();
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " waiting at CMS state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 Thread::current(), _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 while (_foregroundGCIsActive) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 CGC_lock->wait(Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 ConcurrentMarkSweepThread::set_CMS_flag(
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 ConcurrentMarkSweepThread::CMS_cms_has_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 ConcurrentMarkSweepThread::clear_CMS_flag(
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 ConcurrentMarkSweepThread::CMS_cms_wants_token);
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 if (TraceCMSState) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " continuing at CMS state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 Thread::current(), _collectorState);
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2575
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 // Because of the need to lock the free lists and other structures in
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 // the collector, common to all the generations that the collector is
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 // collecting, we need the gc_prologues of individual CMS generations
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 // delegate to their collector. It may have been simpler had the
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 // current infrastructure allowed one to call a prologue on a
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 // collector. In the absence of that we have the generation's
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 // prologue delegate to the collector, which delegates back
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 // some "local" work to a worker method in the individual generations
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 // that it's responsible for collecting, while itself doing any
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 // work common to all generations it's responsible for. A similar
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 // comment applies to the gc_epilogue()'s.
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 // The role of the varaible _between_prologue_and_epilogue is to
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 // enforce the invocation protocol.
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 void CMSCollector::gc_prologue(bool full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 // Call gc_prologue_work() for each CMSGen and PermGen that
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 // we are responsible for.
a61af66fc99e Initial load
duke
parents:
diff changeset
2592
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 // The following locking discipline assumes that we are only called
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 // when the world is stopped.
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 assert(SafepointSynchronize::is_at_safepoint(), "world is stopped assumption");
a61af66fc99e Initial load
duke
parents:
diff changeset
2596
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 // The CMSCollector prologue must call the gc_prologues for the
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 // "generations" (including PermGen if any) that it's responsible
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 // for.
a61af66fc99e Initial load
duke
parents:
diff changeset
2600
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 assert( Thread::current()->is_VM_thread()
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 || ( CMSScavengeBeforeRemark
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 && Thread::current()->is_ConcurrentGC_thread()),
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 "Incorrect thread type for prologue execution");
a61af66fc99e Initial load
duke
parents:
diff changeset
2605
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 if (_between_prologue_and_epilogue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 // We have already been invoked; this is a gc_prologue delegation
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 // from yet another CMS generation that we are responsible for, just
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 // ignore it since all relevant work has already been done.
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2612
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 // set a bit saying prologue has been called; cleared in epilogue
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 _between_prologue_and_epilogue = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 // Claim locks for common data structures, then call gc_prologue_work()
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 // for each CMSGen and PermGen that we are responsible for.
a61af66fc99e Initial load
duke
parents:
diff changeset
2617
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 getFreelistLocks(); // gets free list locks on constituent spaces
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 bitMapLock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
2620
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 // Should call gc_prologue_work() for all cms gens we are responsible for
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 bool registerClosure = _collectorState >= Marking
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 && _collectorState < Sweeping;
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
2624 ModUnionClosure* muc = CollectedHeap::use_parallel_gc_threads() ?
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
2625 &_modUnionClosurePar
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 : &_modUnionClosure;
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 _cmsGen->gc_prologue_work(full, registerClosure, muc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 _permGen->gc_prologue_work(full, registerClosure, muc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2629
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 if (!full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 stats().record_gc0_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2634
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 void ConcurrentMarkSweepGeneration::gc_prologue(bool full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 // Delegate to CMScollector which knows how to coordinate between
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 // this and any other CMS generations that it is responsible for
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 // collecting.
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 collector()->gc_prologue(full);
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2641
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 // This is a "private" interface for use by this generation's CMSCollector.
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 // Not to be called directly by any other entity (for instance,
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 // GenCollectedHeap, which calls the "public" gc_prologue method above).
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 void ConcurrentMarkSweepGeneration::gc_prologue_work(bool full,
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 bool registerClosure, ModUnionClosure* modUnionClosure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 assert(!incremental_collection_failed(), "Shouldn't be set yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 assert(cmsSpace()->preconsumptionDirtyCardClosure() == NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 "Should be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 if (registerClosure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 cmsSpace()->setPreconsumptionDirtyCardClosure(modUnionClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 cmsSpace()->gc_prologue();
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 // Clear stat counters
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 assert(_numObjectsPromoted == 0, "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 assert(_numWordsPromoted == 0, "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 if (Verbose && PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 gclog_or_tty->print("Allocated "SIZE_FORMAT" objects, "
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 SIZE_FORMAT" bytes concurrently",
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 _numObjectsAllocated, _numWordsAllocated*sizeof(HeapWord));
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 _numObjectsAllocated = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 _numWordsAllocated = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 )
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2667
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 void CMSCollector::gc_epilogue(bool full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 // The following locking discipline assumes that we are only called
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 // when the world is stopped.
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 assert(SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 "world is stopped assumption");
a61af66fc99e Initial load
duke
parents:
diff changeset
2673
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 // Currently the CMS epilogue (see CompactibleFreeListSpace) merely checks
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 // if linear allocation blocks need to be appropriately marked to allow the
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 // the blocks to be parsable. We also check here whether we need to nudge the
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 // CMS collector thread to start a new cycle (if it's not already active).
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 assert( Thread::current()->is_VM_thread()
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 || ( CMSScavengeBeforeRemark
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 && Thread::current()->is_ConcurrentGC_thread()),
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 "Incorrect thread type for epilogue execution");
a61af66fc99e Initial load
duke
parents:
diff changeset
2682
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 if (!_between_prologue_and_epilogue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 // We have already been invoked; this is a gc_epilogue delegation
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 // from yet another CMS generation that we are responsible for, just
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 // ignore it since all relevant work has already been done.
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 assert(haveFreelistLocks(), "must have freelist locks");
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
2691
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 _cmsGen->gc_epilogue_work(full);
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 _permGen->gc_epilogue_work(full);
a61af66fc99e Initial load
duke
parents:
diff changeset
2694
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 if (_collectorState == AbortablePreclean || _collectorState == Precleaning) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 // in case sampling was not already enabled, enable it
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 _start_sampling = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 // reset _eden_chunk_array so sampling starts afresh
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 _eden_chunk_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2701
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 size_t cms_used = _cmsGen->cmsSpace()->used();
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 size_t perm_used = _permGen->cmsSpace()->used();
a61af66fc99e Initial load
duke
parents:
diff changeset
2704
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 // update performance counters - this uses a special version of
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 // update_counters() that allows the utilization to be passed as a
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 // parameter, avoiding multiple calls to used().
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 _cmsGen->update_counters(cms_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 _permGen->update_counters(perm_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
2711
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 if (CMSIncrementalMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 icms_update_allocation_limits();
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2715
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 bitMapLock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 releaseFreelistLocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
2718
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 _between_prologue_and_epilogue = false; // ready for next cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2721
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 void ConcurrentMarkSweepGeneration::gc_epilogue(bool full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 collector()->gc_epilogue(full);
a61af66fc99e Initial load
duke
parents:
diff changeset
2724
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 // Also reset promotion tracking in par gc thread states.
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
2726 if (CollectedHeap::use_parallel_gc_threads()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 for (uint i = 0; i < ParallelGCThreads; i++) {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2728 _par_gc_thread_states[i]->promo.stopTrackingPromotions(i);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2732
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 void ConcurrentMarkSweepGeneration::gc_epilogue_work(bool full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 assert(!incremental_collection_failed(), "Should have been cleared");
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 cmsSpace()->setPreconsumptionDirtyCardClosure(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 cmsSpace()->gc_epilogue();
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 // Print stat counters
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 assert(_numObjectsAllocated == 0, "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 assert(_numWordsAllocated == 0, "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 if (Verbose && PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 gclog_or_tty->print("Promoted "SIZE_FORMAT" objects, "
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 SIZE_FORMAT" bytes",
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 _numObjectsPromoted, _numWordsPromoted*sizeof(HeapWord));
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 _numObjectsPromoted = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 _numWordsPromoted = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 )
a61af66fc99e Initial load
duke
parents:
diff changeset
2749
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 if (PrintGC && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 // Call down the chain in contiguous_available needs the freelistLock
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 // so print this out before releasing the freeListLock.
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 gclog_or_tty->print(" Contiguous available "SIZE_FORMAT" bytes ",
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 contiguous_available());
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2757
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 bool CMSCollector::have_cms_token() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 Thread* thr = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 if (thr->is_VM_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 return ConcurrentMarkSweepThread::vm_thread_has_cms_token();
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 } else if (thr->is_ConcurrentGC_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 return ConcurrentMarkSweepThread::cms_thread_has_cms_token();
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 } else if (thr->is_GC_task_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 return ConcurrentMarkSweepThread::vm_thread_has_cms_token() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 ParGCRareEvent_lock->owned_by_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2772
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 // Check reachability of the given heap address in CMS generation,
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 // treating all other generations as roots.
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 bool CMSCollector::is_cms_reachable(HeapWord* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 // We could "guarantee" below, rather than assert, but i'll
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 // leave these as "asserts" so that an adventurous debugger
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 // could try this in the product build provided some subset of
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 // the conditions were met, provided they were intersted in the
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 // results and knew that the computation below wouldn't interfere
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 // with other concurrent computations mutating the structures
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 // being read or written.
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 assert(SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 "Else mutations in object graph will make answer suspect");
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 assert(have_cms_token(), "Should hold cms token");
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 assert(haveFreelistLocks(), "must hold free list locks");
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
2788
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 // Clear the marking bit map array before starting, but, just
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 // for kicks, first report if the given address is already marked
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 gclog_or_tty->print_cr("Start: Address 0x%x is%s marked", addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 _markBitMap.isMarked(addr) ? "" : " not");
a61af66fc99e Initial load
duke
parents:
diff changeset
2793
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 if (verify_after_remark()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 MutexLockerEx x(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 bool result = verification_mark_bm()->isMarked(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 gclog_or_tty->print_cr("TransitiveMark: Address 0x%x %s marked", addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 result ? "IS" : "is NOT");
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 gclog_or_tty->print_cr("Could not compute result");
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2805
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 ////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 // CMS Verification Support
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 ////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 // Following the remark phase, the following invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 // should hold -- each object in the CMS heap which is
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 // marked in markBitMap() should be marked in the verification_mark_bm().
a61af66fc99e Initial load
duke
parents:
diff changeset
2812
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 class VerifyMarkedClosure: public BitMapClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 CMSBitMap* _marks;
a61af66fc99e Initial load
duke
parents:
diff changeset
2815 bool _failed;
a61af66fc99e Initial load
duke
parents:
diff changeset
2816
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 VerifyMarkedClosure(CMSBitMap* bm): _marks(bm), _failed(false) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
2819
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
2820 bool do_bit(size_t offset) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 HeapWord* addr = _marks->offsetToHeapWord(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 if (!_marks->isMarked(addr)) {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2823 oop(addr)->print_on(gclog_or_tty);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 gclog_or_tty->print_cr(" ("INTPTR_FORMAT" should have been marked)", addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 _failed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
2827 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2829
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 bool failed() { return _failed; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2832
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 bool CMSCollector::verify_after_remark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 gclog_or_tty->print(" [Verifying CMS Marking... ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 MutexLockerEx ml(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 static bool init = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2837
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 assert(SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 "Else mutations in object graph will make answer suspect");
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 assert(have_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 "Else there may be mutual interference in use of "
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 " verification data structures");
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 assert(_collectorState > Marking && _collectorState <= Sweeping,
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 "Else marking info checked here may be obsolete");
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 assert(haveFreelistLocks(), "must hold free list locks");
a61af66fc99e Initial load
duke
parents:
diff changeset
2846 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
2847
a61af66fc99e Initial load
duke
parents:
diff changeset
2848
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 // Allocate marking bit map if not already allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 if (!init) { // first time
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 if (!verification_mark_bm()->allocate(_span)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 init = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2856
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 assert(verification_mark_stack()->isEmpty(), "Should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
2858
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 // Turn off refs discovery -- so we will be tracing through refs.
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 // This is as intended, because by this time
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 // GC must already have cleared any refs that need to be cleared,
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 // and traced those that need to be marked; moreover,
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 // the marking done here is not going to intefere in any
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 // way with the marking information used by GC.
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 NoRefDiscovery no_discovery(ref_processor());
a61af66fc99e Initial load
duke
parents:
diff changeset
2866
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
a61af66fc99e Initial load
duke
parents:
diff changeset
2868
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 // Clear any marks from a previous round
a61af66fc99e Initial load
duke
parents:
diff changeset
2870 verification_mark_bm()->clear_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 assert(verification_mark_stack()->isEmpty(), "markStack should be empty");
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2872 verify_work_stacks_empty();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2873
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 gch->ensure_parsability(false); // fill TLABs, but no need to retire them
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 // Update the saved marks which may affect the root scans.
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 gch->save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
2878
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 if (CMSRemarkVerifyVariant == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 // In this first variant of verification, we complete
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 // all marking, then check if the new marks-verctor is
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 // a subset of the CMS marks-vector.
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 verify_after_remark_work_1();
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 } else if (CMSRemarkVerifyVariant == 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 // In this second variant of verification, we flag an error
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 // (i.e. an object reachable in the new marks-vector not reachable
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 // in the CMS marks-vector) immediately, also indicating the
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 // identify of an object (A) that references the unmarked object (B) --
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 // presumably, a mutation to A failed to be picked up by preclean/remark?
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 verify_after_remark_work_2();
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 warning("Unrecognized value %d for CMSRemarkVerifyVariant",
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 CMSRemarkVerifyVariant);
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 gclog_or_tty->print(" done] ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2898
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 void CMSCollector::verify_after_remark_work_1() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
2903
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 // Mark from roots one level into CMS
994
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
2905 MarkRefsIntoClosure notOlder(_span, verification_mark_bm());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
2907
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 gch->gen_process_strong_roots(_cmsGen->level(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 true, // younger gens are roots
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
2910 true, // activate StrongRootsScope
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 true, // collecting perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 SharedHeap::ScanningOption(roots_scanning_options()),
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
2913 &notOlder,
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
2914 true, // walk code active on stacks
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
2915 NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2916
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 // Now mark from the roots
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 assert(_revisitStack.isEmpty(), "Should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 MarkFromRootsClosure markFromRootsClosure(this, _span,
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 verification_mark_bm(), verification_mark_stack(), &_revisitStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 false /* don't yield */, true /* verifying */);
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 assert(_restart_addr == NULL, "Expected pre-condition");
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 verification_mark_bm()->iterate(&markFromRootsClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 while (_restart_addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 // Deal with stack overflow: by restarting at the indicated
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 // address.
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 HeapWord* ra = _restart_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 markFromRootsClosure.reset(ra);
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 _restart_addr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 verification_mark_bm()->iterate(&markFromRootsClosure, ra, _span.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 assert(verification_mark_stack()->isEmpty(), "Should have been drained");
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 // Should reset the revisit stack above, since no class tree
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 // surgery is forthcoming.
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 _revisitStack.reset(); // throwing away all contents
a61af66fc99e Initial load
duke
parents:
diff changeset
2937
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 // Marking completed -- now verify that each bit marked in
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 // verification_mark_bm() is also marked in markBitMap(); flag all
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 // errors by printing corresponding objects.
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 VerifyMarkedClosure vcl(markBitMap());
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 verification_mark_bm()->iterate(&vcl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 if (vcl.failed()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 gclog_or_tty->print("Verification failed");
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2945 Universe::heap()->print_on(gclog_or_tty);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
2946 fatal("CMS: failed marking verification after remark");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2949
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 void CMSCollector::verify_after_remark_work_2() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
2954
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 // Mark from roots one level into CMS
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 MarkRefsIntoVerifyClosure notOlder(_span, verification_mark_bm(),
994
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
2957 markBitMap());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 gch->gen_process_strong_roots(_cmsGen->level(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 true, // younger gens are roots
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
2961 true, // activate StrongRootsScope
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 true, // collecting perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 SharedHeap::ScanningOption(roots_scanning_options()),
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
2964 &notOlder,
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
2965 true, // walk code active on stacks
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
2966 NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2967
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 // Now mark from the roots
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 assert(_revisitStack.isEmpty(), "Should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 MarkFromRootsVerifyClosure markFromRootsClosure(this, _span,
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 verification_mark_bm(), markBitMap(), verification_mark_stack());
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 assert(_restart_addr == NULL, "Expected pre-condition");
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 verification_mark_bm()->iterate(&markFromRootsClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 while (_restart_addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 // Deal with stack overflow: by restarting at the indicated
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 // address.
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 HeapWord* ra = _restart_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 markFromRootsClosure.reset(ra);
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 _restart_addr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 verification_mark_bm()->iterate(&markFromRootsClosure, ra, _span.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 assert(verification_mark_stack()->isEmpty(), "Should have been drained");
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 // Should reset the revisit stack above, since no class tree
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 // surgery is forthcoming.
a61af66fc99e Initial load
duke
parents:
diff changeset
2986 _revisitStack.reset(); // throwing away all contents
a61af66fc99e Initial load
duke
parents:
diff changeset
2987
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 // Marking completed -- now verify that each bit marked in
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 // verification_mark_bm() is also marked in markBitMap(); flag all
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 // errors by printing corresponding objects.
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 VerifyMarkedClosure vcl(markBitMap());
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 verification_mark_bm()->iterate(&vcl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2993 assert(!vcl.failed(), "Else verification above should not have succeeded");
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2995
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 void ConcurrentMarkSweepGeneration::save_marks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 // delegate to CMS space
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 cmsSpace()->save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 for (uint i = 0; i < ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 _par_gc_thread_states[i]->promo.startTrackingPromotions();
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3003
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 bool ConcurrentMarkSweepGeneration::no_allocs_since_save_marks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 return cmsSpace()->no_allocs_since_save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3007
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 #define CMS_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 \
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 void ConcurrentMarkSweepGeneration:: \
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 cl->set_generation(this); \
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 cmsSpace()->oop_since_save_marks_iterate##nv_suffix(cl); \
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 cl->reset_generation(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 save_marks(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3017
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 ALL_SINCE_SAVE_MARKS_CLOSURES(CMS_SINCE_SAVE_MARKS_DEFN)
a61af66fc99e Initial load
duke
parents:
diff changeset
3019
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 ConcurrentMarkSweepGeneration::object_iterate_since_last_GC(ObjectClosure* blk)
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 // Not currently implemented; need to do the following. -- ysr.
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 // dld -- I think that is used for some sort of allocation profiler. So it
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 // really means the objects allocated by the mutator since the last
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 // GC. We could potentially implement this cheaply by recording only
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 // the direct allocations in a side data structure.
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 // I think we probably ought not to be required to support these
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 // iterations at any arbitrary point; I think there ought to be some
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 // call to enable/disable allocation profiling in a generation/space,
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 // and the iterator ought to return the objects allocated in the
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 // gen/space since the enable call, or the last iterator call (which
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 // will probably be at a GC.) That way, for gens like CM&S that would
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 // require some extra data structure to support this, we only pay the
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 // cost when it's in use...
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 cmsSpace()->object_iterate_since_last_GC(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3039
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 ConcurrentMarkSweepGeneration::younger_refs_iterate(OopsInGenClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 cl->set_generation(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 younger_refs_in_space_iterate(_cmsSpace, cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 cl->reset_generation();
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3046
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 ConcurrentMarkSweepGeneration::oop_iterate(MemRegion mr, OopClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 if (freelistLock()->owned_by_self()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 Generation::oop_iterate(mr, cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 Generation::oop_iterate(mr, cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3056
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 ConcurrentMarkSweepGeneration::oop_iterate(OopClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 if (freelistLock()->owned_by_self()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 Generation::oop_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 Generation::oop_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3066
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 ConcurrentMarkSweepGeneration::object_iterate(ObjectClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 if (freelistLock()->owned_by_self()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 Generation::object_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 Generation::object_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3076
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 void
517
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 457
diff changeset
3078 ConcurrentMarkSweepGeneration::safe_object_iterate(ObjectClosure* cl) {
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 457
diff changeset
3079 if (freelistLock()->owned_by_self()) {
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 457
diff changeset
3080 Generation::safe_object_iterate(cl);
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 457
diff changeset
3081 } else {
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 457
diff changeset
3082 MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 457
diff changeset
3083 Generation::safe_object_iterate(cl);
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 457
diff changeset
3084 }
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 457
diff changeset
3085 }
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 457
diff changeset
3086
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 457
diff changeset
3087 void
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 ConcurrentMarkSweepGeneration::pre_adjust_pointers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3090
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 ConcurrentMarkSweepGeneration::post_compact() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3094
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 ConcurrentMarkSweepGeneration::prepare_for_verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 // Fix the linear allocation blocks to look like free blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
3098
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 // are not called when the heap is verified during universe initialization and
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 // at vm shutdown.
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 if (freelistLock()->owned_by_self()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 cmsSpace()->prepare_for_verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 cmsSpace()->prepare_for_verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3109
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 ConcurrentMarkSweepGeneration::verify(bool allow_dirty /* ignored */) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 // are not called when the heap is verified during universe initialization and
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 // at vm shutdown.
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 if (freelistLock()->owned_by_self()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 cmsSpace()->verify(false /* ignored */);
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 cmsSpace()->verify(false /* ignored */);
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3122
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 void CMSCollector::verify(bool allow_dirty /* ignored */) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 _cmsGen->verify(allow_dirty);
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 _permGen->verify(allow_dirty);
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3127
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 bool CMSCollector::overflow_list_is_empty() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 assert(_num_par_pushes >= 0, "Inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 if (_overflow_list == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 assert(_num_par_pushes == 0, "Inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 return _overflow_list == NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3136
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 // The methods verify_work_stacks_empty() and verify_overflow_empty()
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 // merely consolidate assertion checks that appear to occur together frequently.
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 void CMSCollector::verify_work_stacks_empty() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 assert(_markStack.isEmpty(), "Marking stack should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 assert(overflow_list_is_empty(), "Overflow list should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3143
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 void CMSCollector::verify_overflow_empty() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 assert(overflow_list_is_empty(), "Overflow list should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 assert(no_preserved_marks(), "No preserved marks");
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3149
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3150 // Decide if we want to enable class unloading as part of the
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3151 // ensuing concurrent GC cycle. We will collect the perm gen and
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3152 // unload classes if it's the case that:
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3153 // (1) an explicit gc request has been made and the flag
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3154 // ExplicitGCInvokesConcurrentAndUnloadsClasses is set, OR
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3155 // (2) (a) class unloading is enabled at the command line, and
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3156 // (b) (i) perm gen threshold has been crossed, or
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3157 // (ii) old gen is getting really full, or
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3158 // (iii) the previous N CMS collections did not collect the
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3159 // perm gen
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3160 // NOTE: Provided there is no change in the state of the heap between
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3161 // calls to this method, it should have idempotent results. Moreover,
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3162 // its results should be monotonically increasing (i.e. going from 0 to 1,
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3163 // but not 1 to 0) between successive calls between which the heap was
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3164 // not collected. For the implementation below, it must thus rely on
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3165 // the property that concurrent_cycles_since_last_unload()
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3166 // will not decrease unless a collection cycle happened and that
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3167 // _permGen->should_concurrent_collect() and _cmsGen->is_too_full() are
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3168 // themselves also monotonic in that sense. See check_monotonicity()
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3169 // below.
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3170 bool CMSCollector::update_should_unload_classes() {
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3171 _should_unload_classes = false;
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3172 // Condition 1 above
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3173 if (_full_gc_requested && ExplicitGCInvokesConcurrentAndUnloadsClasses) {
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3174 _should_unload_classes = true;
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3175 } else if (CMSClassUnloadingEnabled) { // Condition 2.a above
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3176 // Disjuncts 2.b.(i,ii,iii) above
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3177 _should_unload_classes = (concurrent_cycles_since_last_unload() >=
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3178 CMSClassUnloadingMaxInterval)
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3179 || _permGen->should_concurrent_collect()
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3180 || _cmsGen->is_too_full();
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3181 }
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3182 return _should_unload_classes;
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3183 }
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3184
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3185 bool ConcurrentMarkSweepGeneration::is_too_full() const {
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3186 bool res = should_concurrent_collect();
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3187 res = res && (occupancy() > (double)CMSIsTooFullPercentage/100.0);
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3188 return res;
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3189 }
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3190
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 void CMSCollector::setup_cms_unloading_and_verification_state() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3192 const bool should_verify = VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 || VerifyBeforeExit;
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 const int rso = SharedHeap::SO_Symbols | SharedHeap::SO_Strings
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 | SharedHeap::SO_CodeCache;
a61af66fc99e Initial load
duke
parents:
diff changeset
3196
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3197 if (should_unload_classes()) { // Should unload classes this cycle
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3198 remove_root_scanning_option(rso); // Shrink the root set appropriately
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 set_verifying(should_verify); // Set verification state for this cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 return; // Nothing else needs to be done at this time
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3202
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 // Not unloading classes this cycle
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3204 assert(!should_unload_classes(), "Inconsitency!");
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
3205 if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 // We were not verifying, or we _were_ unloading classes in the last cycle,
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 // AND some verification options are enabled this cycle; in this case,
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 // we must make sure that the deadness map is allocated if not already so,
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 // and cleared (if already allocated previously --
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 // CMSBitMap::sizeInBits() is used to determine if it's allocated).
a61af66fc99e Initial load
duke
parents:
diff changeset
3211 if (perm_gen_verify_bit_map()->sizeInBits() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 if (!perm_gen_verify_bit_map()->allocate(_permGen->reserved())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 warning("Failed to allocate permanent generation verification CMS Bit Map;\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 "permanent generation verification disabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 return; // Note that we leave verification disabled, so we'll retry this
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 // allocation next cycle. We _could_ remember this failure
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 // and skip further attempts and permanently disable verification
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 // attempts if that is considered more desirable.
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 assert(perm_gen_verify_bit_map()->covers(_permGen->reserved()),
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 "_perm_gen_ver_bit_map inconsistency?");
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 perm_gen_verify_bit_map()->clear_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 // Include symbols, strings and code cache elements to prevent their resurrection.
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 add_root_scanning_option(rso);
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 set_verifying(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3228 } else if (verifying() && !should_verify) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 // We were verifying, but some verification flags got disabled.
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 set_verifying(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 // Exclude symbols, strings and code cache elements from root scanning to
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 // reduce IM and RM pauses.
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 remove_root_scanning_option(rso);
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3236
a61af66fc99e Initial load
duke
parents:
diff changeset
3237
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 HeapWord* CMSCollector::block_start(const void* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 const HeapWord* addr = (HeapWord*)p;
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 if (_span.contains(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 if (_cmsGen->cmsSpace()->is_in_reserved(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 return _cmsGen->cmsSpace()->block_start(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 assert(_permGen->cmsSpace()->is_in_reserved(addr),
a61af66fc99e Initial load
duke
parents:
diff changeset
3246 "Inconsistent _span?");
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 return _permGen->cmsSpace()->block_start(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3252 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3253
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
3255 ConcurrentMarkSweepGeneration::expand_and_allocate(size_t word_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
3256 bool tlab,
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 bool parallel) {
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3258 CMSSynchronousYieldRequest yr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3259 assert(!tlab, "Can't deal with TLAB allocation");
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3261 expand(word_size*HeapWordSize, MinHeapDeltaBytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
3262 CMSExpansionCause::_satisfy_allocation);
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 if (GCExpandToAllocateDelayMillis > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3265 }
9
173195ff483a 6642634: Test nsk/regression/b6186200 crashed with SIGSEGV
ysr
parents: 7
diff changeset
3266 return have_lock_and_allocate(word_size, tlab);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3268
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 // YSR: All of this generation expansion/shrinking stuff is an exact copy of
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 // OneContigSpaceCardGeneration, which makes me wonder if we should move this
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 // to CardGeneration and share it...
271
818a18cd69a8 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 196
diff changeset
3272 bool ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes) {
818a18cd69a8 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 196
diff changeset
3273 return CardGeneration::expand(bytes, expand_bytes);
818a18cd69a8 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 196
diff changeset
3274 }
818a18cd69a8 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 196
diff changeset
3275
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
3277 CMSExpansionCause::Cause cause)
a61af66fc99e Initial load
duke
parents:
diff changeset
3278 {
271
818a18cd69a8 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 196
diff changeset
3279
818a18cd69a8 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 196
diff changeset
3280 bool success = expand(bytes, expand_bytes);
818a18cd69a8 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 196
diff changeset
3281
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3282 // remember why we expanded; this information is used
a61af66fc99e Initial load
duke
parents:
diff changeset
3283 // by shouldConcurrentCollect() when making decisions on whether to start
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 // a new CMS cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 if (success) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3286 set_expansion_cause(cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 gclog_or_tty->print_cr("Expanded CMS gen for %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 CMSExpansionCause::to_string(cause));
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3293
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 HeapWord* ConcurrentMarkSweepGeneration::expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 HeapWord* res = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 MutexLocker x(ParGCRareEvent_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 // Expansion by some other thread might make alloc OK now:
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 res = ps->lab.alloc(word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 if (res != NULL) return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
3301 // If there's not enough expansion space available, give up.
a61af66fc99e Initial load
duke
parents:
diff changeset
3302 if (_virtual_space.uncommitted_size() < (word_sz * HeapWordSize)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3303 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3305 // Otherwise, we try expansion.
a61af66fc99e Initial load
duke
parents:
diff changeset
3306 expand(word_sz*HeapWordSize, MinHeapDeltaBytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
3307 CMSExpansionCause::_allocate_par_lab);
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 // Now go around the loop and try alloc again;
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 // A competing par_promote might beat us to the expansion space,
a61af66fc99e Initial load
duke
parents:
diff changeset
3310 // so we may go around the loop again if promotion fails agaion.
a61af66fc99e Initial load
duke
parents:
diff changeset
3311 if (GCExpandToAllocateDelayMillis > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3312 os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3316
a61af66fc99e Initial load
duke
parents:
diff changeset
3317
a61af66fc99e Initial load
duke
parents:
diff changeset
3318 bool ConcurrentMarkSweepGeneration::expand_and_ensure_spooling_space(
a61af66fc99e Initial load
duke
parents:
diff changeset
3319 PromotionInfo* promo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3320 MutexLocker x(ParGCRareEvent_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3321 size_t refill_size_bytes = promo->refillSize() * HeapWordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3323 // Expansion by some other thread might make alloc OK now:
a61af66fc99e Initial load
duke
parents:
diff changeset
3324 if (promo->ensure_spooling_space()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 assert(promo->has_spooling_space(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3326 "Post-condition of successful ensure_spooling_space()");
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3329 // If there's not enough expansion space available, give up.
a61af66fc99e Initial load
duke
parents:
diff changeset
3330 if (_virtual_space.uncommitted_size() < refill_size_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3331 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3333 // Otherwise, we try expansion.
a61af66fc99e Initial load
duke
parents:
diff changeset
3334 expand(refill_size_bytes, MinHeapDeltaBytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 CMSExpansionCause::_allocate_par_spooling_space);
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 // Now go around the loop and try alloc again;
a61af66fc99e Initial load
duke
parents:
diff changeset
3337 // A competing allocation might beat us to the expansion space,
a61af66fc99e Initial load
duke
parents:
diff changeset
3338 // so we may go around the loop again if allocation fails again.
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 if (GCExpandToAllocateDelayMillis > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3344
a61af66fc99e Initial load
duke
parents:
diff changeset
3345
a61af66fc99e Initial load
duke
parents:
diff changeset
3346
a61af66fc99e Initial load
duke
parents:
diff changeset
3347 void ConcurrentMarkSweepGeneration::shrink(size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 assert_locked_or_safepoint(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 size_t size = ReservedSpace::page_align_size_down(bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3350 if (size > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3351 shrink_by(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3354
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 bool ConcurrentMarkSweepGeneration::grow_by(size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3356 assert_locked_or_safepoint(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 bool result = _virtual_space.expand_by(bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 if (result) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 HeapWord* old_end = _cmsSpace->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 size_t new_word_size =
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 heap_word_size(_virtual_space.committed_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3362 MemRegion mr(_cmsSpace->bottom(), new_word_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3363 _bts->resize(new_word_size); // resize the block offset shared array
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 Universe::heap()->barrier_set()->resize_covered_region(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3365 // Hmmmm... why doesn't CFLS::set_end verify locking?
a61af66fc99e Initial load
duke
parents:
diff changeset
3366 // This is quite ugly; FIX ME XXX
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
3367 _cmsSpace->assert_locked(freelistLock());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3368 _cmsSpace->set_end((HeapWord*)_virtual_space.high());
a61af66fc99e Initial load
duke
parents:
diff changeset
3369
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 // update the space and generation capacity counters
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 _space_counters->update_capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 _gen_counters->update_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3375
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 if (Verbose && PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 size_t new_mem_size = _virtual_space.committed_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 size_t old_mem_size = new_mem_size - bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 gclog_or_tty->print_cr("Expanding %s from %ldK by %ldK to %ldK",
a61af66fc99e Initial load
duke
parents:
diff changeset
3380 name(), old_mem_size/K, bytes/K, new_mem_size/K);
a61af66fc99e Initial load
duke
parents:
diff changeset
3381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
3384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3385
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 bool ConcurrentMarkSweepGeneration::grow_to_reserved() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3387 assert_locked_or_safepoint(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3388 bool success = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3389 const size_t remaining_bytes = _virtual_space.uncommitted_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 if (remaining_bytes > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3391 success = grow_by(remaining_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 return success;
a61af66fc99e Initial load
duke
parents:
diff changeset
3395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3396
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 void ConcurrentMarkSweepGeneration::shrink_by(size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 assert_locked_or_safepoint(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 // XXX Fix when compaction is implemented.
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 warning("Shrinking of CMS not yet implemented");
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3404
a61af66fc99e Initial load
duke
parents:
diff changeset
3405
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 // Simple ctor/dtor wrapper for accounting & timer chores around concurrent
a61af66fc99e Initial load
duke
parents:
diff changeset
3407 // phases.
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 class CMSPhaseAccounting: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3410 CMSPhaseAccounting(CMSCollector *collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
3411 const char *phase,
a61af66fc99e Initial load
duke
parents:
diff changeset
3412 bool print_cr = true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 ~CMSPhaseAccounting();
a61af66fc99e Initial load
duke
parents:
diff changeset
3414
a61af66fc99e Initial load
duke
parents:
diff changeset
3415 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
3416 CMSCollector *_collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
3417 const char *_phase;
a61af66fc99e Initial load
duke
parents:
diff changeset
3418 elapsedTimer _wallclock;
a61af66fc99e Initial load
duke
parents:
diff changeset
3419 bool _print_cr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3420
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 // Not MT-safe; so do not pass around these StackObj's
a61af66fc99e Initial load
duke
parents:
diff changeset
3423 // where they may be accessed by other threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
3424 jlong wallclock_millis() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 assert(_wallclock.is_active(), "Wall clock should not stop");
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 _wallclock.stop(); // to record time
a61af66fc99e Initial load
duke
parents:
diff changeset
3427 jlong ret = _wallclock.milliseconds();
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 _wallclock.start(); // restart
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
3430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3432
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 const char *phase,
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 bool print_cr) :
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 _collector(collector), _phase(phase), _print_cr(print_cr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3437
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 _collector->resetYields();
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3441 if (PrintGCDetails && PrintGCTimeStamps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 gclog_or_tty->date_stamp(PrintGCDateStamps);
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 gclog_or_tty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 gclog_or_tty->print_cr(": [%s-concurrent-%s-start]",
a61af66fc99e Initial load
duke
parents:
diff changeset
3445 _collector->cmsGen()->short_name(), _phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3447 _collector->resetTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 _wallclock.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 _collector->startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
3450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3451
a61af66fc99e Initial load
duke
parents:
diff changeset
3452 CMSPhaseAccounting::~CMSPhaseAccounting() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3453 assert(_wallclock.is_active(), "Wall clock should not have stopped");
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 _collector->stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
3455 _wallclock.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3456 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3457 gclog_or_tty->date_stamp(PrintGCDateStamps);
a61af66fc99e Initial load
duke
parents:
diff changeset
3458 if (PrintGCTimeStamps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 gclog_or_tty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
3460 gclog_or_tty->print(": ");
a61af66fc99e Initial load
duke
parents:
diff changeset
3461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]",
a61af66fc99e Initial load
duke
parents:
diff changeset
3463 _collector->cmsGen()->short_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3464 _phase, _collector->timerValue(), _wallclock.seconds());
a61af66fc99e Initial load
duke
parents:
diff changeset
3465 if (_print_cr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3466 gclog_or_tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
3467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3468 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 gclog_or_tty->print_cr(" (CMS-concurrent-%s yielded %d times)", _phase,
a61af66fc99e Initial load
duke
parents:
diff changeset
3470 _collector->yields());
a61af66fc99e Initial load
duke
parents:
diff changeset
3471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3474
a61af66fc99e Initial load
duke
parents:
diff changeset
3475 // CMS work
a61af66fc99e Initial load
duke
parents:
diff changeset
3476
a61af66fc99e Initial load
duke
parents:
diff changeset
3477 // Checkpoint the roots into this generation from outside
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 // this generation. [Note this initial checkpoint need only
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 // be approximate -- we'll do a catch up phase subsequently.]
a61af66fc99e Initial load
duke
parents:
diff changeset
3480 void CMSCollector::checkpointRootsInitial(bool asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 assert(_collectorState == InitialMarking, "Wrong collector state");
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 check_correct_thread_executing();
1703
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
3483 TraceCMSMemoryManagerStats tms(_collectorState);
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1994
diff changeset
3484
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 ReferenceProcessor* rp = ref_processor();
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 SpecializationStats::clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 assert(_restart_addr == NULL, "Control point invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
3488 if (asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 // acquire locks for subsequent manipulations
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 MutexLockerEx x(bitMapLock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3491 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 checkpointRootsInitialWork(asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 rp->verify_no_references_recorded();
a61af66fc99e Initial load
duke
parents:
diff changeset
3494 rp->enable_discovery(); // enable ("weak") refs discovery
a61af66fc99e Initial load
duke
parents:
diff changeset
3495 _collectorState = Marking;
a61af66fc99e Initial load
duke
parents:
diff changeset
3496 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3497 // (Weak) Refs discovery: this is controlled from genCollectedHeap::do_collection
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 // which recognizes if we are a CMS generation, and doesn't try to turn on
a61af66fc99e Initial load
duke
parents:
diff changeset
3499 // discovery; verify that they aren't meddling.
a61af66fc99e Initial load
duke
parents:
diff changeset
3500 assert(!rp->discovery_is_atomic(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3501 "incorrect setting of discovery predicate");
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 assert(!rp->discovery_enabled(), "genCollectedHeap shouldn't control "
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 "ref discovery for this generation kind");
a61af66fc99e Initial load
duke
parents:
diff changeset
3504 // already have locks
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 checkpointRootsInitialWork(asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
3506 rp->enable_discovery(); // now enable ("weak") refs discovery
a61af66fc99e Initial load
duke
parents:
diff changeset
3507 _collectorState = Marking;
a61af66fc99e Initial load
duke
parents:
diff changeset
3508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3509 SpecializationStats::print();
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3511
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 void CMSCollector::checkpointRootsInitialWork(bool asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3513 assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped");
a61af66fc99e Initial load
duke
parents:
diff changeset
3514 assert(_collectorState == InitialMarking, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
3515
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 // If there has not been a GC[n-1] since last GC[n] cycle completed,
a61af66fc99e Initial load
duke
parents:
diff changeset
3517 // precede our marking with a collection of all
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 // younger generations to keep floating garbage to a minimum.
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 // XXX: we won't do this for now -- it's an optimization to be done later.
a61af66fc99e Initial load
duke
parents:
diff changeset
3520
a61af66fc99e Initial load
duke
parents:
diff changeset
3521 // already have locks
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 assert(_markBitMap.isAllClear(), "was reset at end of previous cycle");
a61af66fc99e Initial load
duke
parents:
diff changeset
3524
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 // Setup the verification and class unloading state for this
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 // CMS collection cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 setup_cms_unloading_and_verification_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
3528
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 NOT_PRODUCT(TraceTime t("\ncheckpointRootsInitialWork",
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 PrintGCDetails && Verbose, true, gclog_or_tty);)
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 size_policy()->checkpoint_roots_initial_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3534
a61af66fc99e Initial load
duke
parents:
diff changeset
3535 // Reset all the PLAB chunk arrays if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 reset_survivor_plab_arrays();
a61af66fc99e Initial load
duke
parents:
diff changeset
3538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3539
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3542
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 FalseClosure falseClosure;
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 // In the case of a synchronous collection, we will elide the
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 // remark step, so it's important to catch all the nmethod oops
994
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
3546 // in this step.
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
3547 // The final 'true' flag to gen_process_strong_roots will ensure this.
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
3548 // If 'async' is true, we can relax the nmethod tracing.
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
3549 MarkRefsIntoClosure notOlder(_span, &_markBitMap);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3550 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
3551
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
3554
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 gch->ensure_parsability(false); // fill TLABs, but no need to retire them
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 // Update the saved marks which may affect the root scans.
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 gch->save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3558
a61af66fc99e Initial load
duke
parents:
diff changeset
3559 // weak reference processing has not started yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 ref_processor()->set_enqueuing_is_done(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3561
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 {
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
3563 // This is not needed. DEBUG_ONLY(RememberKlassesChecker imx(true);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 gch->gen_process_strong_roots(_cmsGen->level(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 true, // younger gens are roots
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
3568 true, // activate StrongRootsScope
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 true, // collecting perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 SharedHeap::ScanningOption(roots_scanning_options()),
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
3571 &notOlder,
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
3572 true, // walk all of code cache if (so & SO_CodeCache)
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
3573 NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3575
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 // Clear mod-union table; it will be dirtied in the prologue of
a61af66fc99e Initial load
duke
parents:
diff changeset
3577 // CMS generation per each younger generation collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
3578
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 assert(_modUnionTable.isAllClear(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 "Was cleared in most recent final checkpoint phase"
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 " or no bits are set in the gc_prologue before the start of the next "
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 "subsequent marking phase.");
a61af66fc99e Initial load
duke
parents:
diff changeset
3583
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 // Temporarily disabled, since pre/post-consumption closures don't
a61af66fc99e Initial load
duke
parents:
diff changeset
3585 // care about precleaned cards
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 #if 0
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3588 MemRegion mr = MemRegion((HeapWord*)_virtual_space.low(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 (HeapWord*)_virtual_space.high());
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 _ct->ct_bs()->preclean_dirty_cards(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3593
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 // Save the end of the used_region of the constituent generations
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 // to be used to limit the extent of sweep in each generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 save_sweep_limits();
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 size_policy()->checkpoint_roots_initial_end(gch->gc_cause());
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3602
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 bool CMSCollector::markFromRoots(bool asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 // we might be tempted to assert that:
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 // assert(asynch == !SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 // "inconsistent argument?");
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 // However that wouldn't be right, because it's possible that
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 // a safepoint is indeed in progress as a younger generation
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 // stop-the-world GC happens even as we mark in this generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 assert(_collectorState == Marking, "inconsistent state?");
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 check_correct_thread_executing();
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
3613
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 bool res;
a61af66fc99e Initial load
duke
parents:
diff changeset
3615 if (asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3616
a61af66fc99e Initial load
duke
parents:
diff changeset
3617 // Start the timers for adaptive size policy for the concurrent phases
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 // Do it here so that the foreground MS can use the concurrent
a61af66fc99e Initial load
duke
parents:
diff changeset
3619 // timer since a foreground MS might has the sweep done concurrently
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 // or STW.
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 size_policy()->concurrent_marking_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
3623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3624
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 // Weak ref discovery note: We may be discovering weak
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 // refs in this generation concurrent (but interleaved) with
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 // weak ref discovery by a younger generation collector.
a61af66fc99e Initial load
duke
parents:
diff changeset
3628
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 CMSTokenSyncWithLocks ts(true, bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 CMSPhaseAccounting pa(this, "mark", !PrintGCDetails);
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 res = markFromRootsWork(asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 if (res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 _collectorState = Precleaning;
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 } else { // We failed and a foreground collection wants to take over
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 assert(_foregroundGCIsActive, "internal state inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 assert(_restart_addr == NULL, "foreground will restart from scratch");
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 gclog_or_tty->print_cr("bailing out to foreground collection");
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 size_policy()->concurrent_marking_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 assert(SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 "inconsistent with asynch == false");
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 size_policy()->ms_collection_marking_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 // already have locks
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 res = markFromRootsWork(asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 _collectorState = FinalMarking;
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
3656 size_policy()->ms_collection_marking_end(gch->gc_cause());
a61af66fc99e Initial load
duke
parents:
diff changeset
3657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
3660 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3662
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 bool CMSCollector::markFromRootsWork(bool asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 // iterate over marked bits in bit map, doing a full scan and mark
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 // from these roots using the following algorithm:
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 // . if oop is to the right of the current scan pointer,
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 // mark corresponding bit (we'll process it later)
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 // . else (oop is to left of current scan pointer)
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 // push oop on marking stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 // . drain the marking stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3671
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 // Note that when we do a marking step we need to hold the
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 // bit map lock -- recall that direct allocation (by mutators)
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 // and promotion (by younger generation collectors) is also
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 // marking the bit map. [the so-called allocate live policy.]
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 // Because the implementation of bit map marking is not
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 // robust wrt simultaneous marking of bits in the same word,
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 // we need to make sure that there is no such interference
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 // between concurrent such updates.
a61af66fc99e Initial load
duke
parents:
diff changeset
3680
a61af66fc99e Initial load
duke
parents:
diff changeset
3681 // already have locks
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
3683
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 // Clear the revisit stack, just in case there are any
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 // obsolete contents from a short-circuited previous CMS cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 _revisitStack.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 assert(_revisitStack.isEmpty(), "tabula rasa");
1190
4788266644c1 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 1145
diff changeset
3690 DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 bool result = false;
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
3692 if (CMSConcurrentMTEnabled && ConcGCThreads > 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 result = do_marking_mt(asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3695 result = do_marking_st(asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3699
a61af66fc99e Initial load
duke
parents:
diff changeset
3700 // Forward decl
a61af66fc99e Initial load
duke
parents:
diff changeset
3701 class CMSConcMarkingTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
3702
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 class CMSConcMarkingTerminator: public ParallelTaskTerminator {
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 CMSCollector* _collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 CMSConcMarkingTask* _task;
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3706 public:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 virtual void yield();
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3708
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 // "n_threads" is the number of threads to be terminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 // "queue_set" is a set of work queues of other threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 // "collector" is the CMS collector associated with this task terminator.
a61af66fc99e Initial load
duke
parents:
diff changeset
3712 // "yield" indicates whether we need the gang as a whole to yield.
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3713 CMSConcMarkingTerminator(int n_threads, TaskQueueSetSuper* queue_set, CMSCollector* collector) :
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 ParallelTaskTerminator(n_threads, queue_set),
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3715 _collector(collector) { }
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3716
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3717 void set_task(CMSConcMarkingTask* task) {
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3718 _task = task;
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3719 }
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3720 };
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3721
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3722 class CMSConcMarkingTerminatorTerminator: public TerminatorTerminator {
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3723 CMSConcMarkingTask* _task;
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3724 public:
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3725 bool should_exit_termination();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 void set_task(CMSConcMarkingTask* task) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 _task = task;
a61af66fc99e Initial load
duke
parents:
diff changeset
3728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3730
a61af66fc99e Initial load
duke
parents:
diff changeset
3731 // MT Concurrent Marking Task
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 class CMSConcMarkingTask: public YieldingFlexibleGangTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
3733 CMSCollector* _collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
3734 int _n_workers; // requested/desired # workers
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 bool _asynch;
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 bool _result;
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 CompactibleFreeListSpace* _cms_space;
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 CompactibleFreeListSpace* _perm_space;
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3739 char _pad_front[64]; // padding to ...
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3740 HeapWord* _global_finger; // ... avoid sharing cache line
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3741 char _pad_back[64];
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3742 HeapWord* _restart_addr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3743
a61af66fc99e Initial load
duke
parents:
diff changeset
3744 // Exposed here for yielding support
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 Mutex* const _bit_map_lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
3746
a61af66fc99e Initial load
duke
parents:
diff changeset
3747 // The per thread work queues, available here for stealing
a61af66fc99e Initial load
duke
parents:
diff changeset
3748 OopTaskQueueSet* _task_queues;
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3749
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3750 // Termination (and yielding) support
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 CMSConcMarkingTerminator _term;
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3752 CMSConcMarkingTerminatorTerminator _term_term;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3753
a61af66fc99e Initial load
duke
parents:
diff changeset
3754 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3755 CMSConcMarkingTask(CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
3756 CompactibleFreeListSpace* cms_space,
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 CompactibleFreeListSpace* perm_space,
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
3758 bool asynch,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3759 YieldingFlexibleWorkGang* workers,
a61af66fc99e Initial load
duke
parents:
diff changeset
3760 OopTaskQueueSet* task_queues):
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 YieldingFlexibleGangTask("Concurrent marking done multi-threaded"),
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 _collector(collector),
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 _cms_space(cms_space),
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 _perm_space(perm_space),
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
3765 _asynch(asynch), _n_workers(0), _result(true),
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
3766 _task_queues(task_queues),
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3767 _term(_n_workers, task_queues, _collector),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 _bit_map_lock(collector->bitMapLock())
a61af66fc99e Initial load
duke
parents:
diff changeset
3769 {
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
3770 _requested_size = _n_workers;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3771 _term.set_task(this);
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3772 _term_term.set_task(this);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3773 assert(_cms_space->bottom() < _perm_space->bottom(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 "Finger incorrectly initialized below");
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3775 _restart_addr = _global_finger = _cms_space->bottom();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3777
a61af66fc99e Initial load
duke
parents:
diff changeset
3778
a61af66fc99e Initial load
duke
parents:
diff changeset
3779 OopTaskQueueSet* task_queues() { return _task_queues; }
a61af66fc99e Initial load
duke
parents:
diff changeset
3780
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3782
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 HeapWord** global_finger_addr() { return &_global_finger; }
a61af66fc99e Initial load
duke
parents:
diff changeset
3784
a61af66fc99e Initial load
duke
parents:
diff changeset
3785 CMSConcMarkingTerminator* terminator() { return &_term; }
a61af66fc99e Initial load
duke
parents:
diff changeset
3786
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
3787 virtual void set_for_termination(int active_workers) {
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
3788 terminator()->reset_for_reuse(active_workers);
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
3789 }
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
3790
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 void work(int i);
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3792 bool should_yield() {
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3793 return ConcurrentMarkSweepThread::should_yield()
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3794 && !_collector->foregroundGCIsActive()
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3795 && _asynch;
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3796 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3797
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 virtual void coordinator_yield(); // stuff done by coordinator
a61af66fc99e Initial load
duke
parents:
diff changeset
3799 bool result() { return _result; }
a61af66fc99e Initial load
duke
parents:
diff changeset
3800
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 void reset(HeapWord* ra) {
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3802 assert(_global_finger >= _cms_space->end(), "Postcondition of ::work(i)");
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3803 assert(_global_finger >= _perm_space->end(), "Postcondition of ::work(i)");
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3804 assert(ra < _perm_space->end(), "ra too large");
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3805 _restart_addr = _global_finger = ra;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3806 _term.reset_for_reuse();
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3808
a61af66fc99e Initial load
duke
parents:
diff changeset
3809 static bool get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 OopTaskQueue* work_q);
a61af66fc99e Initial load
duke
parents:
diff changeset
3811
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
3813 void do_scan_and_mark(int i, CompactibleFreeListSpace* sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3814 void do_work_steal(int i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3815 void bump_global_finger(HeapWord* f);
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3817
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3818 bool CMSConcMarkingTerminatorTerminator::should_exit_termination() {
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3819 assert(_task != NULL, "Error");
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3820 return _task->yielding();
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3821 // Note that we do not need the disjunct || _task->should_yield() above
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3822 // because we want terminating threads to yield only if the task
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3823 // is already in the midst of yielding, which happens only after at least one
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3824 // thread has yielded.
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3825 }
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3826
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3827 void CMSConcMarkingTerminator::yield() {
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
3828 if (_task->should_yield()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3829 _task->yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
3830 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3831 ParallelTaskTerminator::yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
3832 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3834
a61af66fc99e Initial load
duke
parents:
diff changeset
3835 ////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
3836 // Concurrent Marking Algorithm Sketch
a61af66fc99e Initial load
duke
parents:
diff changeset
3837 ////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
3838 // Until all tasks exhausted (both spaces):
a61af66fc99e Initial load
duke
parents:
diff changeset
3839 // -- claim next available chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
3840 // -- bump global finger via CAS
a61af66fc99e Initial load
duke
parents:
diff changeset
3841 // -- find first object that starts in this chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
3842 // and start scanning bitmap from that position
a61af66fc99e Initial load
duke
parents:
diff changeset
3843 // -- scan marked objects for oops
a61af66fc99e Initial load
duke
parents:
diff changeset
3844 // -- CAS-mark target, and if successful:
a61af66fc99e Initial load
duke
parents:
diff changeset
3845 // . if target oop is above global finger (volatile read)
a61af66fc99e Initial load
duke
parents:
diff changeset
3846 // nothing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
3847 // . if target oop is in chunk and above local finger
a61af66fc99e Initial load
duke
parents:
diff changeset
3848 // then nothing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
3849 // . else push on work-queue
a61af66fc99e Initial load
duke
parents:
diff changeset
3850 // -- Deal with possible overflow issues:
a61af66fc99e Initial load
duke
parents:
diff changeset
3851 // . local work-queue overflow causes stuff to be pushed on
a61af66fc99e Initial load
duke
parents:
diff changeset
3852 // global (common) overflow queue
a61af66fc99e Initial load
duke
parents:
diff changeset
3853 // . always first empty local work queue
a61af66fc99e Initial load
duke
parents:
diff changeset
3854 // . then get a batch of oops from global work queue if any
a61af66fc99e Initial load
duke
parents:
diff changeset
3855 // . then do work stealing
a61af66fc99e Initial load
duke
parents:
diff changeset
3856 // -- When all tasks claimed (both spaces)
a61af66fc99e Initial load
duke
parents:
diff changeset
3857 // and local work queue empty,
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 // then in a loop do:
a61af66fc99e Initial load
duke
parents:
diff changeset
3859 // . check global overflow stack; steal a batch of oops and trace
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 // . try to steal from other threads oif GOS is empty
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 // . if neither is available, offer termination
a61af66fc99e Initial load
duke
parents:
diff changeset
3862 // -- Terminate and return result
a61af66fc99e Initial load
duke
parents:
diff changeset
3863 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 void CMSConcMarkingTask::work(int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3865 elapsedTimer _timer;
a61af66fc99e Initial load
duke
parents:
diff changeset
3866 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3867 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3868
a61af66fc99e Initial load
duke
parents:
diff changeset
3869 DEBUG_ONLY(_collector->verify_overflow_empty();)
a61af66fc99e Initial load
duke
parents:
diff changeset
3870
a61af66fc99e Initial load
duke
parents:
diff changeset
3871 // Before we begin work, our work queue should be empty
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 assert(work_queue(i)->size() == 0, "Expected to be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
3873 // Scan the bitmap covering _cms_space, tracing through grey objects.
a61af66fc99e Initial load
duke
parents:
diff changeset
3874 _timer.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
3875 do_scan_and_mark(i, _cms_space);
a61af66fc99e Initial load
duke
parents:
diff changeset
3876 _timer.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3877 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3878 gclog_or_tty->print_cr("Finished cms space scanning in %dth thread: %3.3f sec",
a61af66fc99e Initial load
duke
parents:
diff changeset
3879 i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
a61af66fc99e Initial load
duke
parents:
diff changeset
3880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3881
a61af66fc99e Initial load
duke
parents:
diff changeset
3882 // ... do the same for the _perm_space
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 _timer.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3884 _timer.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
3885 do_scan_and_mark(i, _perm_space);
a61af66fc99e Initial load
duke
parents:
diff changeset
3886 _timer.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3887 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3888 gclog_or_tty->print_cr("Finished perm space scanning in %dth thread: %3.3f sec",
a61af66fc99e Initial load
duke
parents:
diff changeset
3889 i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
a61af66fc99e Initial load
duke
parents:
diff changeset
3890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3891
a61af66fc99e Initial load
duke
parents:
diff changeset
3892 // ... do work stealing
a61af66fc99e Initial load
duke
parents:
diff changeset
3893 _timer.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3894 _timer.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
3895 do_work_steal(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3896 _timer.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3897 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3898 gclog_or_tty->print_cr("Finished work stealing in %dth thread: %3.3f sec",
a61af66fc99e Initial load
duke
parents:
diff changeset
3899 i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
a61af66fc99e Initial load
duke
parents:
diff changeset
3900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3901 assert(_collector->_markStack.isEmpty(), "Should have been emptied");
a61af66fc99e Initial load
duke
parents:
diff changeset
3902 assert(work_queue(i)->size() == 0, "Should have been emptied");
a61af66fc99e Initial load
duke
parents:
diff changeset
3903 // Note that under the current task protocol, the
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 // following assertion is true even of the spaces
a61af66fc99e Initial load
duke
parents:
diff changeset
3905 // expanded since the completion of the concurrent
a61af66fc99e Initial load
duke
parents:
diff changeset
3906 // marking. XXX This will likely change under a strict
a61af66fc99e Initial load
duke
parents:
diff changeset
3907 // ABORT semantics.
a61af66fc99e Initial load
duke
parents:
diff changeset
3908 assert(_global_finger > _cms_space->end() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3909 _global_finger >= _perm_space->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3910 "All tasks have been completed");
a61af66fc99e Initial load
duke
parents:
diff changeset
3911 DEBUG_ONLY(_collector->verify_overflow_empty();)
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3913
a61af66fc99e Initial load
duke
parents:
diff changeset
3914 void CMSConcMarkingTask::bump_global_finger(HeapWord* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 HeapWord* read = _global_finger;
a61af66fc99e Initial load
duke
parents:
diff changeset
3916 HeapWord* cur = read;
a61af66fc99e Initial load
duke
parents:
diff changeset
3917 while (f > read) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3918 cur = read;
a61af66fc99e Initial load
duke
parents:
diff changeset
3919 read = (HeapWord*) Atomic::cmpxchg_ptr(f, &_global_finger, cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
3920 if (cur == read) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3921 // our cas succeeded
a61af66fc99e Initial load
duke
parents:
diff changeset
3922 assert(_global_finger >= f, "protocol consistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
3923 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3927
a61af66fc99e Initial load
duke
parents:
diff changeset
3928 // This is really inefficient, and should be redone by
a61af66fc99e Initial load
duke
parents:
diff changeset
3929 // using (not yet available) block-read and -write interfaces to the
a61af66fc99e Initial load
duke
parents:
diff changeset
3930 // stack and the work_queue. XXX FIX ME !!!
a61af66fc99e Initial load
duke
parents:
diff changeset
3931 bool CMSConcMarkingTask::get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
a61af66fc99e Initial load
duke
parents:
diff changeset
3932 OopTaskQueue* work_q) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 // Fast lock-free check
a61af66fc99e Initial load
duke
parents:
diff changeset
3934 if (ovflw_stk->length() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3935 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3937 assert(work_q->size() == 0, "Shouldn't steal");
a61af66fc99e Initial load
duke
parents:
diff changeset
3938 MutexLockerEx ml(ovflw_stk->par_lock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3939 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 // Grab up to 1/4 the size of the work queue
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 628
diff changeset
3941 size_t num = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 (size_t)ParGCDesiredObjsFromOverflowList);
a61af66fc99e Initial load
duke
parents:
diff changeset
3943 num = MIN2(num, ovflw_stk->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
3944 for (int i = (int) num; i > 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 oop cur = ovflw_stk->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3946 assert(cur != NULL, "Counted wrong?");
a61af66fc99e Initial load
duke
parents:
diff changeset
3947 work_q->push(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
3948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 return num > 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3951
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 void CMSConcMarkingTask::do_scan_and_mark(int i, CompactibleFreeListSpace* sp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3953 SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3954 int n_tasks = pst->n_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3955 // We allow that there may be no tasks to do here because
a61af66fc99e Initial load
duke
parents:
diff changeset
3956 // we are restarting after a stack overflow.
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3957 assert(pst->valid() || n_tasks == 0, "Uninitialized use?");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3958 int nth_task = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3959
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3960 HeapWord* aligned_start = sp->bottom();
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3961 if (sp->used_region().contains(_restart_addr)) {
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3962 // Align down to a card boundary for the start of 0th task
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3963 // for this space.
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3964 aligned_start =
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3965 (HeapWord*)align_size_down((uintptr_t)_restart_addr,
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3966 CardTableModRefBS::card_size);
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3967 }
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3968
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 size_t chunk_size = sp->marking_task_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3970 while (!pst->is_task_claimed(/* reference */ nth_task)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3971 // Having claimed the nth task in this space,
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 // compute the chunk that it corresponds to:
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3973 MemRegion span = MemRegion(aligned_start + nth_task*chunk_size,
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3974 aligned_start + (nth_task+1)*chunk_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3975 // Try and bump the global finger via a CAS;
a61af66fc99e Initial load
duke
parents:
diff changeset
3976 // note that we need to do the global finger bump
a61af66fc99e Initial load
duke
parents:
diff changeset
3977 // _before_ taking the intersection below, because
a61af66fc99e Initial load
duke
parents:
diff changeset
3978 // the task corresponding to that region will be
a61af66fc99e Initial load
duke
parents:
diff changeset
3979 // deemed done even if the used_region() expands
a61af66fc99e Initial load
duke
parents:
diff changeset
3980 // because of allocation -- as it almost certainly will
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 // during start-up while the threads yield in the
a61af66fc99e Initial load
duke
parents:
diff changeset
3982 // closure below.
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 HeapWord* finger = span.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
3984 bump_global_finger(finger); // atomically
a61af66fc99e Initial load
duke
parents:
diff changeset
3985 // There are null tasks here corresponding to chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
3986 // beyond the "top" address of the space.
a61af66fc99e Initial load
duke
parents:
diff changeset
3987 span = span.intersection(sp->used_region());
a61af66fc99e Initial load
duke
parents:
diff changeset
3988 if (!span.is_empty()) { // Non-null task
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3989 HeapWord* prev_obj;
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3990 assert(!span.contains(_restart_addr) || nth_task == 0,
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3991 "Inconsistency");
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3992 if (nth_task == 0) {
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3993 // For the 0th task, we'll not need to compute a block_start.
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3994 if (span.contains(_restart_addr)) {
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3995 // In the case of a restart because of stack overflow,
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3996 // we might additionally skip a chunk prefix.
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3997 prev_obj = _restart_addr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3998 } else {
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
3999 prev_obj = span.start();
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4000 }
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4001 } else {
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4002 // We want to skip the first object because
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4003 // the protocol is to scan any object in its entirety
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4004 // that _starts_ in this span; a fortiori, any
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4005 // object starting in an earlier span is scanned
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4006 // as part of an earlier claimed task.
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4007 // Below we use the "careful" version of block_start
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4008 // so we do not try to navigate uninitialized objects.
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4009 prev_obj = sp->block_start_careful(span.start());
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4010 // Below we use a variant of block_size that uses the
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4011 // Printezis bits to avoid waiting for allocated
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4012 // objects to become initialized/parsable.
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4013 while (prev_obj < span.start()) {
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4014 size_t sz = sp->block_size_no_stall(prev_obj, _collector);
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4015 if (sz > 0) {
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4016 prev_obj += sz;
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4017 } else {
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4018 // In this case we may end up doing a bit of redundant
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4019 // scanning, but that appears unavoidable, short of
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4020 // locking the free list locks; see bug 6324141.
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4021 break;
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4022 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4024 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4025 if (prev_obj < span.end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4026 MemRegion my_span = MemRegion(prev_obj, span.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
4027 // Do the marking work within a non-empty span --
a61af66fc99e Initial load
duke
parents:
diff changeset
4028 // the last argument to the constructor indicates whether the
a61af66fc99e Initial load
duke
parents:
diff changeset
4029 // iteration should be incremental with periodic yields.
a61af66fc99e Initial load
duke
parents:
diff changeset
4030 Par_MarkFromRootsClosure cl(this, _collector, my_span,
a61af66fc99e Initial load
duke
parents:
diff changeset
4031 &_collector->_markBitMap,
a61af66fc99e Initial load
duke
parents:
diff changeset
4032 work_queue(i),
a61af66fc99e Initial load
duke
parents:
diff changeset
4033 &_collector->_markStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
4034 &_collector->_revisitStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
4035 _asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
4036 _collector->_markBitMap.iterate(&cl, my_span.start(), my_span.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
4037 } // else nothing to do for this task
a61af66fc99e Initial load
duke
parents:
diff changeset
4038 } // else nothing to do for this task
a61af66fc99e Initial load
duke
parents:
diff changeset
4039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4040 // We'd be tempted to assert here that since there are no
a61af66fc99e Initial load
duke
parents:
diff changeset
4041 // more tasks left to claim in this space, the global_finger
a61af66fc99e Initial load
duke
parents:
diff changeset
4042 // must exceed space->top() and a fortiori space->end(). However,
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 // that would not quite be correct because the bumping of
a61af66fc99e Initial load
duke
parents:
diff changeset
4044 // global_finger occurs strictly after the claiming of a task,
a61af66fc99e Initial load
duke
parents:
diff changeset
4045 // so by the time we reach here the global finger may not yet
a61af66fc99e Initial load
duke
parents:
diff changeset
4046 // have been bumped up by the thread that claimed the last
a61af66fc99e Initial load
duke
parents:
diff changeset
4047 // task.
a61af66fc99e Initial load
duke
parents:
diff changeset
4048 pst->all_tasks_completed();
a61af66fc99e Initial load
duke
parents:
diff changeset
4049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4050
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4051 class Par_ConcMarkingClosure: public Par_KlassRememberingOopClosure {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4052 private:
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4053 CMSConcMarkingTask* _task;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4054 MemRegion _span;
a61af66fc99e Initial load
duke
parents:
diff changeset
4055 CMSBitMap* _bit_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
4056 CMSMarkStack* _overflow_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
4057 OopTaskQueue* _work_queue;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4058 protected:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4059 DO_OOP_WORK_DEFN
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4060 public:
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4061 Par_ConcMarkingClosure(CMSCollector* collector, CMSConcMarkingTask* task, OopTaskQueue* work_queue,
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4062 CMSBitMap* bit_map, CMSMarkStack* overflow_stack,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4063 CMSMarkStack* revisit_stack):
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4064 Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4065 _task(task),
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4066 _span(collector->_span),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4067 _work_queue(work_queue),
a61af66fc99e Initial load
duke
parents:
diff changeset
4068 _bit_map(bit_map),
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4069 _overflow_stack(overflow_stack)
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4070 { }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4071 virtual void do_oop(oop* p);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4072 virtual void do_oop(narrowOop* p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4073 void trim_queue(size_t max);
a61af66fc99e Initial load
duke
parents:
diff changeset
4074 void handle_stack_overflow(HeapWord* lost);
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4075 void do_yield_check() {
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4076 if (_task->should_yield()) {
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4077 _task->yield();
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4078 }
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4079 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4080 };
a61af66fc99e Initial load
duke
parents:
diff changeset
4081
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4082 // Grey object scanning during work stealing phase --
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4083 // the salient assumption here is that any references
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4084 // that are in these stolen objects being scanned must
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4085 // already have been initialized (else they would not have
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4086 // been published), so we do not need to check for
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4087 // uninitialized objects before pushing here.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4088 void Par_ConcMarkingClosure::do_oop(oop obj) {
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4089 assert(obj->is_oop_or_null(true), "expected an oop or NULL");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4090 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4091 // Check if oop points into the CMS generation
a61af66fc99e Initial load
duke
parents:
diff changeset
4092 // and is not marked
a61af66fc99e Initial load
duke
parents:
diff changeset
4093 if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 // a white object ...
a61af66fc99e Initial load
duke
parents:
diff changeset
4095 // If we manage to "claim" the object, by being the
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 // first thread to mark it, then we push it on our
a61af66fc99e Initial load
duke
parents:
diff changeset
4097 // marking stack
a61af66fc99e Initial load
duke
parents:
diff changeset
4098 if (_bit_map->par_mark(addr)) { // ... now grey
a61af66fc99e Initial load
duke
parents:
diff changeset
4099 // push on work queue (grey set)
a61af66fc99e Initial load
duke
parents:
diff changeset
4100 bool simulate_overflow = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4101 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
4102 if (CMSMarkStackOverflowALot &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4103 _collector->simulate_overflow()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4104 // simulate a stack overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
4105 simulate_overflow = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4107 )
a61af66fc99e Initial load
duke
parents:
diff changeset
4108 if (simulate_overflow ||
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4109 !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 // stack overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
4111 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
a61af66fc99e Initial load
duke
parents:
diff changeset
4113 SIZE_FORMAT, _overflow_stack->capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
4114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4115 // We cannot assert that the overflow stack is full because
a61af66fc99e Initial load
duke
parents:
diff changeset
4116 // it may have been emptied since.
a61af66fc99e Initial load
duke
parents:
diff changeset
4117 assert(simulate_overflow ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4118 _work_queue->size() == _work_queue->max_elems(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4119 "Else push should have succeeded");
a61af66fc99e Initial load
duke
parents:
diff changeset
4120 handle_stack_overflow(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4122 } // Else, some other thread got there first
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4123 do_yield_check();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4126
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4127 void Par_ConcMarkingClosure::do_oop(oop* p) { Par_ConcMarkingClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4128 void Par_ConcMarkingClosure::do_oop(narrowOop* p) { Par_ConcMarkingClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4129
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4130 void Par_ConcMarkingClosure::trim_queue(size_t max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4131 while (_work_queue->size() > max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4132 oop new_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
4133 if (_work_queue->pop_local(new_oop)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4134 assert(new_oop->is_oop(), "Should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
4135 assert(_bit_map->isMarked((HeapWord*)new_oop), "Grey object");
a61af66fc99e Initial load
duke
parents:
diff changeset
4136 assert(_span.contains((HeapWord*)new_oop), "Not in span");
a61af66fc99e Initial load
duke
parents:
diff changeset
4137 assert(new_oop->is_parsable(), "Should be parsable");
a61af66fc99e Initial load
duke
parents:
diff changeset
4138 new_oop->oop_iterate(this); // do_oop() above
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4139 do_yield_check();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4143
a61af66fc99e Initial load
duke
parents:
diff changeset
4144 // Upon stack overflow, we discard (part of) the stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
4145 // remembering the least address amongst those discarded
a61af66fc99e Initial load
duke
parents:
diff changeset
4146 // in CMSCollector's _restart_address.
a61af66fc99e Initial load
duke
parents:
diff changeset
4147 void Par_ConcMarkingClosure::handle_stack_overflow(HeapWord* lost) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4148 // We need to do this under a mutex to prevent other
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
4149 // workers from interfering with the work done below.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4150 MutexLockerEx ml(_overflow_stack->par_lock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4151 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
4152 // Remember the least grey address discarded
a61af66fc99e Initial load
duke
parents:
diff changeset
4153 HeapWord* ra = (HeapWord*)_overflow_stack->least_value(lost);
a61af66fc99e Initial load
duke
parents:
diff changeset
4154 _collector->lower_restart_addr(ra);
a61af66fc99e Initial load
duke
parents:
diff changeset
4155 _overflow_stack->reset(); // discard stack contents
a61af66fc99e Initial load
duke
parents:
diff changeset
4156 _overflow_stack->expand(); // expand the stack if possible
a61af66fc99e Initial load
duke
parents:
diff changeset
4157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4158
a61af66fc99e Initial load
duke
parents:
diff changeset
4159
a61af66fc99e Initial load
duke
parents:
diff changeset
4160 void CMSConcMarkingTask::do_work_steal(int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4161 OopTaskQueue* work_q = work_queue(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
4162 oop obj_to_scan;
a61af66fc99e Initial load
duke
parents:
diff changeset
4163 CMSBitMap* bm = &(_collector->_markBitMap);
a61af66fc99e Initial load
duke
parents:
diff changeset
4164 CMSMarkStack* ovflw = &(_collector->_markStack);
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4165 CMSMarkStack* revisit = &(_collector->_revisitStack);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4166 int* seed = _collector->hash_seed(i);
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4167 Par_ConcMarkingClosure cl(_collector, this, work_q, bm, ovflw, revisit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4168 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4169 cl.trim_queue(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4170 assert(work_q->size() == 0, "Should have been emptied above");
a61af66fc99e Initial load
duke
parents:
diff changeset
4171 if (get_work_from_overflow_stack(ovflw, work_q)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4172 // Can't assert below because the work obtained from the
a61af66fc99e Initial load
duke
parents:
diff changeset
4173 // overflow stack may already have been stolen from us.
a61af66fc99e Initial load
duke
parents:
diff changeset
4174 // assert(work_q->size() > 0, "Work from overflow stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
4175 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
4176 } else if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4177 assert(obj_to_scan->is_oop(), "Should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
4178 assert(bm->isMarked((HeapWord*)obj_to_scan), "Grey object");
a61af66fc99e Initial load
duke
parents:
diff changeset
4179 obj_to_scan->oop_iterate(&cl);
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4180 } else if (terminator()->offer_termination(&_term_term)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4181 assert(work_q->size() == 0, "Impossible!");
a61af66fc99e Initial load
duke
parents:
diff changeset
4182 break;
1837
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4183 } else if (yielding() || should_yield()) {
c99c53f07c14 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 1836
diff changeset
4184 yield();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4188
a61af66fc99e Initial load
duke
parents:
diff changeset
4189 // This is run by the CMS (coordinator) thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
4190 void CMSConcMarkingTask::coordinator_yield() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4191 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4192 "CMS thread should hold CMS token");
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4193 DEBUG_ONLY(RememberKlassesChecker mux(false);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4194 // First give up the locks, then yield, then re-lock
a61af66fc99e Initial load
duke
parents:
diff changeset
4195 // We should probably use a constructor/destructor idiom to
a61af66fc99e Initial load
duke
parents:
diff changeset
4196 // do this unlock/lock or modify the MutexUnlocker class to
a61af66fc99e Initial load
duke
parents:
diff changeset
4197 // serve our purpose. XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
4198 assert_lock_strong(_bit_map_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
4199 _bit_map_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
4200 ConcurrentMarkSweepThread::desynchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4201 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
4202 _collector->stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4203 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4204 _collector->incrementYields();
a61af66fc99e Initial load
duke
parents:
diff changeset
4205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4206 _collector->icms_wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
4207
a61af66fc99e Initial load
duke
parents:
diff changeset
4208 // It is possible for whichever thread initiated the yield request
a61af66fc99e Initial load
duke
parents:
diff changeset
4209 // not to get a chance to wake up and take the bitmap lock between
a61af66fc99e Initial load
duke
parents:
diff changeset
4210 // this thread releasing it and reacquiring it. So, while the
a61af66fc99e Initial load
duke
parents:
diff changeset
4211 // should_yield() flag is on, let's sleep for a bit to give the
a61af66fc99e Initial load
duke
parents:
diff changeset
4212 // other thread a chance to wake up. The limit imposed on the number
a61af66fc99e Initial load
duke
parents:
diff changeset
4213 // of iterations is defensive, to avoid any unforseen circumstances
a61af66fc99e Initial load
duke
parents:
diff changeset
4214 // putting us into an infinite loop. Since it's always been this
a61af66fc99e Initial load
duke
parents:
diff changeset
4215 // (coordinator_yield()) method that was observed to cause the
a61af66fc99e Initial load
duke
parents:
diff changeset
4216 // problem, we are using a parameter (CMSCoordinatorYieldSleepCount)
a61af66fc99e Initial load
duke
parents:
diff changeset
4217 // which is by default non-zero. For the other seven methods that
a61af66fc99e Initial load
duke
parents:
diff changeset
4218 // also perform the yield operation, as are using a different
a61af66fc99e Initial load
duke
parents:
diff changeset
4219 // parameter (CMSYieldSleepCount) which is by default zero. This way we
a61af66fc99e Initial load
duke
parents:
diff changeset
4220 // can enable the sleeping for those methods too, if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
4221 // See 6442774.
a61af66fc99e Initial load
duke
parents:
diff changeset
4222 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4223 // We really need to reconsider the synchronization between the GC
a61af66fc99e Initial load
duke
parents:
diff changeset
4224 // thread and the yield-requesting threads in the future and we
a61af66fc99e Initial load
duke
parents:
diff changeset
4225 // should really use wait/notify, which is the recommended
a61af66fc99e Initial load
duke
parents:
diff changeset
4226 // way of doing this type of interaction. Additionally, we should
a61af66fc99e Initial load
duke
parents:
diff changeset
4227 // consolidate the eight methods that do the yield operation and they
a61af66fc99e Initial load
duke
parents:
diff changeset
4228 // are almost identical into one for better maintenability and
a61af66fc99e Initial load
duke
parents:
diff changeset
4229 // readability. See 6445193.
a61af66fc99e Initial load
duke
parents:
diff changeset
4230 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4231 // Tony 2006.06.29
a61af66fc99e Initial load
duke
parents:
diff changeset
4232 for (unsigned i = 0; i < CMSCoordinatorYieldSleepCount &&
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4233 ConcurrentMarkSweepThread::should_yield() &&
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
4234 !CMSCollector::foregroundGCIsActive(); ++i) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4235 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4236 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
4237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4238
a61af66fc99e Initial load
duke
parents:
diff changeset
4239 ConcurrentMarkSweepThread::synchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4240 _bit_map_lock->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
4241 _collector->startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4243
a61af66fc99e Initial load
duke
parents:
diff changeset
4244 bool CMSCollector::do_marking_mt(bool asynch) {
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
4245 assert(ConcGCThreads > 0 && conc_workers() != NULL, "precondition");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4246 // In the future this would be determined ergonomically, based
a61af66fc99e Initial load
duke
parents:
diff changeset
4247 // on #cpu's, # active mutator threads (and load), and mutation rate.
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
4248 int num_workers = ConcGCThreads;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4249
a61af66fc99e Initial load
duke
parents:
diff changeset
4250 CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
4251 CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
4252
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
4253 CMSConcMarkingTask tsk(this,
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
4254 cms_space,
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
4255 perm_space,
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
4256 asynch,
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
4257 conc_workers(),
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
4258 task_queues());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4259
a61af66fc99e Initial load
duke
parents:
diff changeset
4260 // Since the actual number of workers we get may be different
a61af66fc99e Initial load
duke
parents:
diff changeset
4261 // from the number we requested above, do we need to do anything different
a61af66fc99e Initial load
duke
parents:
diff changeset
4262 // below? In particular, may be we need to subclass the SequantialSubTasksDone
a61af66fc99e Initial load
duke
parents:
diff changeset
4263 // class?? XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
4264 cms_space ->initialize_sequential_subtasks_for_marking(num_workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
4265 perm_space->initialize_sequential_subtasks_for_marking(num_workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
4266
a61af66fc99e Initial load
duke
parents:
diff changeset
4267 // Refs discovery is already non-atomic.
a61af66fc99e Initial load
duke
parents:
diff changeset
4268 assert(!ref_processor()->discovery_is_atomic(), "Should be non-atomic");
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
4269 assert(ref_processor()->discovery_is_mt(), "Discovery should be MT");
1190
4788266644c1 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 1145
diff changeset
4270 DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4271 conc_workers()->start_task(&tsk);
a61af66fc99e Initial load
duke
parents:
diff changeset
4272 while (tsk.yielded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4273 tsk.coordinator_yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
4274 conc_workers()->continue_task(&tsk);
a61af66fc99e Initial load
duke
parents:
diff changeset
4275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4276 // If the task was aborted, _restart_addr will be non-NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
4277 assert(tsk.completed() || _restart_addr != NULL, "Inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
4278 while (_restart_addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4279 // XXX For now we do not make use of ABORTED state and have not
a61af66fc99e Initial load
duke
parents:
diff changeset
4280 // yet implemented the right abort semantics (even in the original
a61af66fc99e Initial load
duke
parents:
diff changeset
4281 // single-threaded CMS case). That needs some more investigation
a61af66fc99e Initial load
duke
parents:
diff changeset
4282 // and is deferred for now; see CR# TBF. 07252005YSR. XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
4283 assert(!CMSAbortSemantics || tsk.aborted(), "Inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
4284 // If _restart_addr is non-NULL, a marking stack overflow
605
98cb887364d3 6810672: Comment typos
twisti
parents: 534
diff changeset
4285 // occurred; we need to do a fresh marking iteration from the
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4286 // indicated restart address.
a61af66fc99e Initial load
duke
parents:
diff changeset
4287 if (_foregroundGCIsActive && asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4288 // We may be running into repeated stack overflows, having
a61af66fc99e Initial load
duke
parents:
diff changeset
4289 // reached the limit of the stack size, while making very
a61af66fc99e Initial load
duke
parents:
diff changeset
4290 // slow forward progress. It may be best to bail out and
a61af66fc99e Initial load
duke
parents:
diff changeset
4291 // let the foreground collector do its job.
a61af66fc99e Initial load
duke
parents:
diff changeset
4292 // Clear _restart_addr, so that foreground GC
a61af66fc99e Initial load
duke
parents:
diff changeset
4293 // works from scratch. This avoids the headache of
a61af66fc99e Initial load
duke
parents:
diff changeset
4294 // a "rescan" which would otherwise be needed because
a61af66fc99e Initial load
duke
parents:
diff changeset
4295 // of the dirty mod union table & card table.
a61af66fc99e Initial load
duke
parents:
diff changeset
4296 _restart_addr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4297 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4299 // Adjust the task to restart from _restart_addr
a61af66fc99e Initial load
duke
parents:
diff changeset
4300 tsk.reset(_restart_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4301 cms_space ->initialize_sequential_subtasks_for_marking(num_workers,
a61af66fc99e Initial load
duke
parents:
diff changeset
4302 _restart_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4303 perm_space->initialize_sequential_subtasks_for_marking(num_workers,
a61af66fc99e Initial load
duke
parents:
diff changeset
4304 _restart_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4305 _restart_addr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4306 // Get the workers going again
a61af66fc99e Initial load
duke
parents:
diff changeset
4307 conc_workers()->start_task(&tsk);
a61af66fc99e Initial load
duke
parents:
diff changeset
4308 while (tsk.yielded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4309 tsk.coordinator_yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
4310 conc_workers()->continue_task(&tsk);
a61af66fc99e Initial load
duke
parents:
diff changeset
4311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4313 assert(tsk.completed(), "Inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
4314 assert(tsk.result() == true, "Inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
4315 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4317
a61af66fc99e Initial load
duke
parents:
diff changeset
4318 bool CMSCollector::do_marking_st(bool asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4319 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4320 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4321
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
4322 // Temporarily make refs discovery single threaded (non-MT)
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
4323 ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4324 MarkFromRootsClosure markFromRootsClosure(this, _span, &_markBitMap,
a61af66fc99e Initial load
duke
parents:
diff changeset
4325 &_markStack, &_revisitStack, CMSYield && asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
4326 // the last argument to iterate indicates whether the iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
4327 // should be incremental with periodic yields.
a61af66fc99e Initial load
duke
parents:
diff changeset
4328 _markBitMap.iterate(&markFromRootsClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
4329 // If _restart_addr is non-NULL, a marking stack overflow
605
98cb887364d3 6810672: Comment typos
twisti
parents: 534
diff changeset
4330 // occurred; we need to do a fresh iteration from the
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4331 // indicated restart address.
a61af66fc99e Initial load
duke
parents:
diff changeset
4332 while (_restart_addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4333 if (_foregroundGCIsActive && asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4334 // We may be running into repeated stack overflows, having
a61af66fc99e Initial load
duke
parents:
diff changeset
4335 // reached the limit of the stack size, while making very
a61af66fc99e Initial load
duke
parents:
diff changeset
4336 // slow forward progress. It may be best to bail out and
a61af66fc99e Initial load
duke
parents:
diff changeset
4337 // let the foreground collector do its job.
a61af66fc99e Initial load
duke
parents:
diff changeset
4338 // Clear _restart_addr, so that foreground GC
a61af66fc99e Initial load
duke
parents:
diff changeset
4339 // works from scratch. This avoids the headache of
a61af66fc99e Initial load
duke
parents:
diff changeset
4340 // a "rescan" which would otherwise be needed because
a61af66fc99e Initial load
duke
parents:
diff changeset
4341 // of the dirty mod union table & card table.
a61af66fc99e Initial load
duke
parents:
diff changeset
4342 _restart_addr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4343 return false; // indicating failure to complete marking
a61af66fc99e Initial load
duke
parents:
diff changeset
4344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4345 // Deal with stack overflow:
a61af66fc99e Initial load
duke
parents:
diff changeset
4346 // we restart marking from _restart_addr
a61af66fc99e Initial load
duke
parents:
diff changeset
4347 HeapWord* ra = _restart_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4348 markFromRootsClosure.reset(ra);
a61af66fc99e Initial load
duke
parents:
diff changeset
4349 _restart_addr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4350 _markBitMap.iterate(&markFromRootsClosure, ra, _span.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
4351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4352 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4354
a61af66fc99e Initial load
duke
parents:
diff changeset
4355 void CMSCollector::preclean() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4356 check_correct_thread_executing();
a61af66fc99e Initial load
duke
parents:
diff changeset
4357 assert(Thread::current()->is_ConcurrentGC_thread(), "Wrong thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
4358 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4359 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4360 _abort_preclean = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4361 if (CMSPrecleaningEnabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4362 _eden_chunk_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4363 size_t used = get_eden_used();
a61af66fc99e Initial load
duke
parents:
diff changeset
4364 size_t capacity = get_eden_capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
4365 // Don't start sampling unless we will get sufficiently
a61af66fc99e Initial load
duke
parents:
diff changeset
4366 // many samples.
a61af66fc99e Initial load
duke
parents:
diff changeset
4367 if (used < (capacity/(CMSScheduleRemarkSamplingRatio * 100)
a61af66fc99e Initial load
duke
parents:
diff changeset
4368 * CMSScheduleRemarkEdenPenetration)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4369 _start_sampling = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4370 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4371 _start_sampling = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4373 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
4374 CMSPhaseAccounting pa(this, "preclean", !PrintGCDetails);
a61af66fc99e Initial load
duke
parents:
diff changeset
4375 preclean_work(CMSPrecleanRefLists1, CMSPrecleanSurvivors1);
a61af66fc99e Initial load
duke
parents:
diff changeset
4376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4377 CMSTokenSync x(true); // is cms thread
a61af66fc99e Initial load
duke
parents:
diff changeset
4378 if (CMSPrecleaningEnabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4379 sample_eden();
a61af66fc99e Initial load
duke
parents:
diff changeset
4380 _collectorState = AbortablePreclean;
a61af66fc99e Initial load
duke
parents:
diff changeset
4381 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4382 _collectorState = FinalMarking;
a61af66fc99e Initial load
duke
parents:
diff changeset
4383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4384 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4385 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4387
a61af66fc99e Initial load
duke
parents:
diff changeset
4388 // Try and schedule the remark such that young gen
a61af66fc99e Initial load
duke
parents:
diff changeset
4389 // occupancy is CMSScheduleRemarkEdenPenetration %.
a61af66fc99e Initial load
duke
parents:
diff changeset
4390 void CMSCollector::abortable_preclean() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4391 check_correct_thread_executing();
a61af66fc99e Initial load
duke
parents:
diff changeset
4392 assert(CMSPrecleaningEnabled, "Inconsistent control state");
a61af66fc99e Initial load
duke
parents:
diff changeset
4393 assert(_collectorState == AbortablePreclean, "Inconsistent control state");
a61af66fc99e Initial load
duke
parents:
diff changeset
4394
a61af66fc99e Initial load
duke
parents:
diff changeset
4395 // If Eden's current occupancy is below this threshold,
a61af66fc99e Initial load
duke
parents:
diff changeset
4396 // immediately schedule the remark; else preclean
a61af66fc99e Initial load
duke
parents:
diff changeset
4397 // past the next scavenge in an effort to
a61af66fc99e Initial load
duke
parents:
diff changeset
4398 // schedule the pause as described avove. By choosing
a61af66fc99e Initial load
duke
parents:
diff changeset
4399 // CMSScheduleRemarkEdenSizeThreshold >= max eden size
a61af66fc99e Initial load
duke
parents:
diff changeset
4400 // we will never do an actual abortable preclean cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
4401 if (get_eden_used() > CMSScheduleRemarkEdenSizeThreshold) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4402 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
4403 CMSPhaseAccounting pa(this, "abortable-preclean", !PrintGCDetails);
a61af66fc99e Initial load
duke
parents:
diff changeset
4404 // We need more smarts in the abortable preclean
a61af66fc99e Initial load
duke
parents:
diff changeset
4405 // loop below to deal with cases where allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
4406 // in young gen is very very slow, and our precleaning
a61af66fc99e Initial load
duke
parents:
diff changeset
4407 // is running a losing race against a horde of
a61af66fc99e Initial load
duke
parents:
diff changeset
4408 // mutators intent on flooding us with CMS updates
a61af66fc99e Initial load
duke
parents:
diff changeset
4409 // (dirty cards).
a61af66fc99e Initial load
duke
parents:
diff changeset
4410 // One, admittedly dumb, strategy is to give up
a61af66fc99e Initial load
duke
parents:
diff changeset
4411 // after a certain number of abortable precleaning loops
a61af66fc99e Initial load
duke
parents:
diff changeset
4412 // or after a certain maximum time. We want to make
a61af66fc99e Initial load
duke
parents:
diff changeset
4413 // this smarter in the next iteration.
a61af66fc99e Initial load
duke
parents:
diff changeset
4414 // XXX FIX ME!!! YSR
a61af66fc99e Initial load
duke
parents:
diff changeset
4415 size_t loops = 0, workdone = 0, cumworkdone = 0, waited = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4416 while (!(should_abort_preclean() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4417 ConcurrentMarkSweepThread::should_terminate())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4418 workdone = preclean_work(CMSPrecleanRefLists2, CMSPrecleanSurvivors2);
a61af66fc99e Initial load
duke
parents:
diff changeset
4419 cumworkdone += workdone;
a61af66fc99e Initial load
duke
parents:
diff changeset
4420 loops++;
a61af66fc99e Initial load
duke
parents:
diff changeset
4421 // Voluntarily terminate abortable preclean phase if we have
a61af66fc99e Initial load
duke
parents:
diff changeset
4422 // been at it for too long.
a61af66fc99e Initial load
duke
parents:
diff changeset
4423 if ((CMSMaxAbortablePrecleanLoops != 0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4424 loops >= CMSMaxAbortablePrecleanLoops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4425 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4426 gclog_or_tty->print(" CMS: abort preclean due to loops ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4428 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4430 if (pa.wallclock_millis() > CMSMaxAbortablePrecleanTime) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4431 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4432 gclog_or_tty->print(" CMS: abort preclean due to time ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4434 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4436 // If we are doing little work each iteration, we should
a61af66fc99e Initial load
duke
parents:
diff changeset
4437 // take a short break.
a61af66fc99e Initial load
duke
parents:
diff changeset
4438 if (workdone < CMSAbortablePrecleanMinWorkPerIteration) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4439 // Sleep for some time, waiting for work to accumulate
a61af66fc99e Initial load
duke
parents:
diff changeset
4440 stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4441 cmsThread()->wait_on_cms_lock(CMSAbortablePrecleanWaitMillis);
a61af66fc99e Initial load
duke
parents:
diff changeset
4442 startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4443 waited++;
a61af66fc99e Initial load
duke
parents:
diff changeset
4444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4446 if (PrintCMSStatistics > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4447 gclog_or_tty->print(" [%d iterations, %d waits, %d cards)] ",
a61af66fc99e Initial load
duke
parents:
diff changeset
4448 loops, waited, cumworkdone);
a61af66fc99e Initial load
duke
parents:
diff changeset
4449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4451 CMSTokenSync x(true); // is cms thread
a61af66fc99e Initial load
duke
parents:
diff changeset
4452 if (_collectorState != Idling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4453 assert(_collectorState == AbortablePreclean,
a61af66fc99e Initial load
duke
parents:
diff changeset
4454 "Spontaneous state transition?");
a61af66fc99e Initial load
duke
parents:
diff changeset
4455 _collectorState = FinalMarking;
a61af66fc99e Initial load
duke
parents:
diff changeset
4456 } // Else, a foreground collection completed this CMS cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
4457 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4459
a61af66fc99e Initial load
duke
parents:
diff changeset
4460 // Respond to an Eden sampling opportunity
a61af66fc99e Initial load
duke
parents:
diff changeset
4461 void CMSCollector::sample_eden() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4462 // Make sure a young gc cannot sneak in between our
a61af66fc99e Initial load
duke
parents:
diff changeset
4463 // reading and recording of a sample.
a61af66fc99e Initial load
duke
parents:
diff changeset
4464 assert(Thread::current()->is_ConcurrentGC_thread(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4465 "Only the cms thread may collect Eden samples");
a61af66fc99e Initial load
duke
parents:
diff changeset
4466 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4467 "Should collect samples while holding CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
4468 if (!_start_sampling) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4469 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4471 if (_eden_chunk_array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4472 if (_eden_chunk_index < _eden_chunk_capacity) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4473 _eden_chunk_array[_eden_chunk_index] = *_top_addr; // take sample
a61af66fc99e Initial load
duke
parents:
diff changeset
4474 assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
4475 "Unexpected state of Eden");
a61af66fc99e Initial load
duke
parents:
diff changeset
4476 // We'd like to check that what we just sampled is an oop-start address;
a61af66fc99e Initial load
duke
parents:
diff changeset
4477 // however, we cannot do that here since the object may not yet have been
a61af66fc99e Initial load
duke
parents:
diff changeset
4478 // initialized. So we'll instead do the check when we _use_ this sample
a61af66fc99e Initial load
duke
parents:
diff changeset
4479 // later.
a61af66fc99e Initial load
duke
parents:
diff changeset
4480 if (_eden_chunk_index == 0 ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4481 (pointer_delta(_eden_chunk_array[_eden_chunk_index],
a61af66fc99e Initial load
duke
parents:
diff changeset
4482 _eden_chunk_array[_eden_chunk_index-1])
a61af66fc99e Initial load
duke
parents:
diff changeset
4483 >= CMSSamplingGrain)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4484 _eden_chunk_index++; // commit sample
a61af66fc99e Initial load
duke
parents:
diff changeset
4485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4488 if ((_collectorState == AbortablePreclean) && !_abort_preclean) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4489 size_t used = get_eden_used();
a61af66fc99e Initial load
duke
parents:
diff changeset
4490 size_t capacity = get_eden_capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
4491 assert(used <= capacity, "Unexpected state of Eden");
a61af66fc99e Initial load
duke
parents:
diff changeset
4492 if (used > (capacity/100 * CMSScheduleRemarkEdenPenetration)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4493 _abort_preclean = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4497
a61af66fc99e Initial load
duke
parents:
diff changeset
4498
a61af66fc99e Initial load
duke
parents:
diff changeset
4499 size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4500 assert(_collectorState == Precleaning ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4501 _collectorState == AbortablePreclean, "incorrect state");
a61af66fc99e Initial load
duke
parents:
diff changeset
4502 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4503 HandleMark hm;
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
4504
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
4505 // Precleaning is currently not MT but the reference processor
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
4506 // may be set for MT. Disable it temporarily here.
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
4507 ReferenceProcessor* rp = ref_processor();
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
4508 ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(rp, false);
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
4509
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4510 // Do one pass of scrubbing the discovered reference lists
a61af66fc99e Initial load
duke
parents:
diff changeset
4511 // to remove any reference objects with strongly-reachable
a61af66fc99e Initial load
duke
parents:
diff changeset
4512 // referents.
a61af66fc99e Initial load
duke
parents:
diff changeset
4513 if (clean_refs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4514 CMSPrecleanRefsYieldClosure yield_cl(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
4515 assert(rp->span().equals(_span), "Spans should be equal");
a61af66fc99e Initial load
duke
parents:
diff changeset
4516 CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4517 &_markStack, &_revisitStack,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4518 true /* preclean */);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4519 CMSDrainMarkingStackClosure complete_trace(this,
452
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
4520 _span, &_markBitMap, &_markStack,
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
4521 &keep_alive, true /* preclean */);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4522
a61af66fc99e Initial load
duke
parents:
diff changeset
4523 // We don't want this step to interfere with a young
a61af66fc99e Initial load
duke
parents:
diff changeset
4524 // collection because we don't want to take CPU
a61af66fc99e Initial load
duke
parents:
diff changeset
4525 // or memory bandwidth away from the young GC threads
a61af66fc99e Initial load
duke
parents:
diff changeset
4526 // (which may be as many as there are CPUs).
a61af66fc99e Initial load
duke
parents:
diff changeset
4527 // Note that we don't need to protect ourselves from
a61af66fc99e Initial load
duke
parents:
diff changeset
4528 // interference with mutators because they can't
a61af66fc99e Initial load
duke
parents:
diff changeset
4529 // manipulate the discovered reference lists nor affect
a61af66fc99e Initial load
duke
parents:
diff changeset
4530 // the computed reachability of the referents, the
a61af66fc99e Initial load
duke
parents:
diff changeset
4531 // only properties manipulated by the precleaning
a61af66fc99e Initial load
duke
parents:
diff changeset
4532 // of these reference lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
4533 stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4534 CMSTokenSyncWithLocks x(true /* is cms thread */,
a61af66fc99e Initial load
duke
parents:
diff changeset
4535 bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
4536 startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4537 sample_eden();
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4538
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4539 // The following will yield to allow foreground
a61af66fc99e Initial load
duke
parents:
diff changeset
4540 // collection to proceed promptly. XXX YSR:
a61af66fc99e Initial load
duke
parents:
diff changeset
4541 // The code in this method may need further
a61af66fc99e Initial load
duke
parents:
diff changeset
4542 // tweaking for better performance and some restructuring
a61af66fc99e Initial load
duke
parents:
diff changeset
4543 // for cleaner interfaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
4544 rp->preclean_discovered_references(
a61af66fc99e Initial load
duke
parents:
diff changeset
4545 rp->is_alive_non_header(), &keep_alive, &complete_trace,
1190
4788266644c1 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 1145
diff changeset
4546 &yield_cl, should_unload_classes());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4548
a61af66fc99e Initial load
duke
parents:
diff changeset
4549 if (clean_survivor) { // preclean the active survivor space(s)
a61af66fc99e Initial load
duke
parents:
diff changeset
4550 assert(_young_gen->kind() == Generation::DefNew ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4551 _young_gen->kind() == Generation::ParNew ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4552 _young_gen->kind() == Generation::ASParNew,
a61af66fc99e Initial load
duke
parents:
diff changeset
4553 "incorrect type for cast");
a61af66fc99e Initial load
duke
parents:
diff changeset
4554 DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
a61af66fc99e Initial load
duke
parents:
diff changeset
4555 PushAndMarkClosure pam_cl(this, _span, ref_processor(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4556 &_markBitMap, &_modUnionTable,
a61af66fc99e Initial load
duke
parents:
diff changeset
4557 &_markStack, &_revisitStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
4558 true /* precleaning phase */);
a61af66fc99e Initial load
duke
parents:
diff changeset
4559 stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4560 CMSTokenSyncWithLocks ts(true /* is cms thread */,
a61af66fc99e Initial load
duke
parents:
diff changeset
4561 bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
4562 startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4563 unsigned int before_count =
a61af66fc99e Initial load
duke
parents:
diff changeset
4564 GenCollectedHeap::heap()->total_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
4565 SurvivorSpacePrecleanClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
4566 sss_cl(this, _span, &_markBitMap, &_markStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
4567 &pam_cl, before_count, CMSYield);
1190
4788266644c1 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 1145
diff changeset
4568 DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4569 dng->from()->object_iterate_careful(&sss_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4570 dng->to()->object_iterate_careful(&sss_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4572 MarkRefsIntoAndScanClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
4573 mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
a61af66fc99e Initial load
duke
parents:
diff changeset
4574 &_markStack, &_revisitStack, this, CMSYield,
a61af66fc99e Initial load
duke
parents:
diff changeset
4575 true /* precleaning phase */);
a61af66fc99e Initial load
duke
parents:
diff changeset
4576 // CAUTION: The following closure has persistent state that may need to
a61af66fc99e Initial load
duke
parents:
diff changeset
4577 // be reset upon a decrease in the sequence of addresses it
a61af66fc99e Initial load
duke
parents:
diff changeset
4578 // processes.
a61af66fc99e Initial load
duke
parents:
diff changeset
4579 ScanMarkedObjectsAgainCarefullyClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
4580 smoac_cl(this, _span,
a61af66fc99e Initial load
duke
parents:
diff changeset
4581 &_markBitMap, &_markStack, &_revisitStack, &mrias_cl, CMSYield);
a61af66fc99e Initial load
duke
parents:
diff changeset
4582
a61af66fc99e Initial load
duke
parents:
diff changeset
4583 // Preclean dirty cards in ModUnionTable and CardTable using
a61af66fc99e Initial load
duke
parents:
diff changeset
4584 // appropriate convergence criterion;
a61af66fc99e Initial load
duke
parents:
diff changeset
4585 // repeat CMSPrecleanIter times unless we find that
a61af66fc99e Initial load
duke
parents:
diff changeset
4586 // we are losing.
a61af66fc99e Initial load
duke
parents:
diff changeset
4587 assert(CMSPrecleanIter < 10, "CMSPrecleanIter is too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
4588 assert(CMSPrecleanNumerator < CMSPrecleanDenominator,
a61af66fc99e Initial load
duke
parents:
diff changeset
4589 "Bad convergence multiplier");
a61af66fc99e Initial load
duke
parents:
diff changeset
4590 assert(CMSPrecleanThreshold >= 100,
a61af66fc99e Initial load
duke
parents:
diff changeset
4591 "Unreasonably low CMSPrecleanThreshold");
a61af66fc99e Initial load
duke
parents:
diff changeset
4592
a61af66fc99e Initial load
duke
parents:
diff changeset
4593 size_t numIter, cumNumCards, lastNumCards, curNumCards;
a61af66fc99e Initial load
duke
parents:
diff changeset
4594 for (numIter = 0, cumNumCards = lastNumCards = curNumCards = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4595 numIter < CMSPrecleanIter;
a61af66fc99e Initial load
duke
parents:
diff changeset
4596 numIter++, lastNumCards = curNumCards, cumNumCards += curNumCards) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4597 curNumCards = preclean_mod_union_table(_cmsGen, &smoac_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4598 if (CMSPermGenPrecleaningEnabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4599 curNumCards += preclean_mod_union_table(_permGen, &smoac_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4601 if (Verbose && PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4602 gclog_or_tty->print(" (modUnionTable: %d cards)", curNumCards);
a61af66fc99e Initial load
duke
parents:
diff changeset
4603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4604 // Either there are very few dirty cards, so re-mark
a61af66fc99e Initial load
duke
parents:
diff changeset
4605 // pause will be small anyway, or our pre-cleaning isn't
a61af66fc99e Initial load
duke
parents:
diff changeset
4606 // that much faster than the rate at which cards are being
a61af66fc99e Initial load
duke
parents:
diff changeset
4607 // dirtied, so we might as well stop and re-mark since
a61af66fc99e Initial load
duke
parents:
diff changeset
4608 // precleaning won't improve our re-mark time by much.
a61af66fc99e Initial load
duke
parents:
diff changeset
4609 if (curNumCards <= CMSPrecleanThreshold ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4610 (numIter > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4611 (curNumCards * CMSPrecleanDenominator >
a61af66fc99e Initial load
duke
parents:
diff changeset
4612 lastNumCards * CMSPrecleanNumerator))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4613 numIter++;
a61af66fc99e Initial load
duke
parents:
diff changeset
4614 cumNumCards += curNumCards;
a61af66fc99e Initial load
duke
parents:
diff changeset
4615 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4618 curNumCards = preclean_card_table(_cmsGen, &smoac_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4619 if (CMSPermGenPrecleaningEnabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4620 curNumCards += preclean_card_table(_permGen, &smoac_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4622 cumNumCards += curNumCards;
a61af66fc99e Initial load
duke
parents:
diff changeset
4623 if (PrintGCDetails && PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4624 gclog_or_tty->print_cr(" (cardTable: %d cards, re-scanned %d cards, %d iterations)",
a61af66fc99e Initial load
duke
parents:
diff changeset
4625 curNumCards, cumNumCards, numIter);
a61af66fc99e Initial load
duke
parents:
diff changeset
4626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4627 return cumNumCards; // as a measure of useful work done
a61af66fc99e Initial load
duke
parents:
diff changeset
4628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4629
a61af66fc99e Initial load
duke
parents:
diff changeset
4630 // PRECLEANING NOTES:
a61af66fc99e Initial load
duke
parents:
diff changeset
4631 // Precleaning involves:
a61af66fc99e Initial load
duke
parents:
diff changeset
4632 // . reading the bits of the modUnionTable and clearing the set bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
4633 // . For the cards corresponding to the set bits, we scan the
a61af66fc99e Initial load
duke
parents:
diff changeset
4634 // objects on those cards. This means we need the free_list_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
4635 // so that we can safely iterate over the CMS space when scanning
a61af66fc99e Initial load
duke
parents:
diff changeset
4636 // for oops.
a61af66fc99e Initial load
duke
parents:
diff changeset
4637 // . When we scan the objects, we'll be both reading and setting
a61af66fc99e Initial load
duke
parents:
diff changeset
4638 // marks in the marking bit map, so we'll need the marking bit map.
a61af66fc99e Initial load
duke
parents:
diff changeset
4639 // . For protecting _collector_state transitions, we take the CGC_lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
4640 // Note that any races in the reading of of card table entries by the
a61af66fc99e Initial load
duke
parents:
diff changeset
4641 // CMS thread on the one hand and the clearing of those entries by the
a61af66fc99e Initial load
duke
parents:
diff changeset
4642 // VM thread or the setting of those entries by the mutator threads on the
a61af66fc99e Initial load
duke
parents:
diff changeset
4643 // other are quite benign. However, for efficiency it makes sense to keep
a61af66fc99e Initial load
duke
parents:
diff changeset
4644 // the VM thread from racing with the CMS thread while the latter is
a61af66fc99e Initial load
duke
parents:
diff changeset
4645 // dirty card info to the modUnionTable. We therefore also use the
a61af66fc99e Initial load
duke
parents:
diff changeset
4646 // CGC_lock to protect the reading of the card table and the mod union
a61af66fc99e Initial load
duke
parents:
diff changeset
4647 // table by the CM thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
4648 // . We run concurrently with mutator updates, so scanning
a61af66fc99e Initial load
duke
parents:
diff changeset
4649 // needs to be done carefully -- we should not try to scan
a61af66fc99e Initial load
duke
parents:
diff changeset
4650 // potentially uninitialized objects.
a61af66fc99e Initial load
duke
parents:
diff changeset
4651 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4652 // Locking strategy: While holding the CGC_lock, we scan over and
a61af66fc99e Initial load
duke
parents:
diff changeset
4653 // reset a maximal dirty range of the mod union / card tables, then lock
a61af66fc99e Initial load
duke
parents:
diff changeset
4654 // the free_list_lock and bitmap lock to do a full marking, then
a61af66fc99e Initial load
duke
parents:
diff changeset
4655 // release these locks; and repeat the cycle. This allows for a
a61af66fc99e Initial load
duke
parents:
diff changeset
4656 // certain amount of fairness in the sharing of these locks between
a61af66fc99e Initial load
duke
parents:
diff changeset
4657 // the CMS collector on the one hand, and the VM thread and the
a61af66fc99e Initial load
duke
parents:
diff changeset
4658 // mutators on the other.
a61af66fc99e Initial load
duke
parents:
diff changeset
4659
a61af66fc99e Initial load
duke
parents:
diff changeset
4660 // NOTE: preclean_mod_union_table() and preclean_card_table()
a61af66fc99e Initial load
duke
parents:
diff changeset
4661 // further below are largely identical; if you need to modify
a61af66fc99e Initial load
duke
parents:
diff changeset
4662 // one of these methods, please check the other method too.
a61af66fc99e Initial load
duke
parents:
diff changeset
4663
a61af66fc99e Initial load
duke
parents:
diff changeset
4664 size_t CMSCollector::preclean_mod_union_table(
a61af66fc99e Initial load
duke
parents:
diff changeset
4665 ConcurrentMarkSweepGeneration* gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
4666 ScanMarkedObjectsAgainCarefullyClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4667 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4668 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4669
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4670 // Turn off checking for this method but turn it back on
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4671 // selectively. There are yield points in this method
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4672 // but it is difficult to turn the checking off just around
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4673 // the yield points. It is simpler to selectively turn
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4674 // it on.
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4675 DEBUG_ONLY(RememberKlassesChecker mux(false);)
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4676
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4677 // strategy: starting with the first card, accumulate contiguous
a61af66fc99e Initial load
duke
parents:
diff changeset
4678 // ranges of dirty cards; clear these cards, then scan the region
a61af66fc99e Initial load
duke
parents:
diff changeset
4679 // covered by these cards.
a61af66fc99e Initial load
duke
parents:
diff changeset
4680
a61af66fc99e Initial load
duke
parents:
diff changeset
4681 // Since all of the MUT is committed ahead, we can just use
a61af66fc99e Initial load
duke
parents:
diff changeset
4682 // that, in case the generations expand while we are precleaning.
a61af66fc99e Initial load
duke
parents:
diff changeset
4683 // It might also be fine to just use the committed part of the
a61af66fc99e Initial load
duke
parents:
diff changeset
4684 // generation, but we might potentially miss cards when the
a61af66fc99e Initial load
duke
parents:
diff changeset
4685 // generation is rapidly expanding while we are in the midst
a61af66fc99e Initial load
duke
parents:
diff changeset
4686 // of precleaning.
a61af66fc99e Initial load
duke
parents:
diff changeset
4687 HeapWord* startAddr = gen->reserved().start();
a61af66fc99e Initial load
duke
parents:
diff changeset
4688 HeapWord* endAddr = gen->reserved().end();
a61af66fc99e Initial load
duke
parents:
diff changeset
4689
a61af66fc99e Initial load
duke
parents:
diff changeset
4690 cl->setFreelistLock(gen->freelistLock()); // needed for yielding
a61af66fc99e Initial load
duke
parents:
diff changeset
4691
a61af66fc99e Initial load
duke
parents:
diff changeset
4692 size_t numDirtyCards, cumNumDirtyCards;
a61af66fc99e Initial load
duke
parents:
diff changeset
4693 HeapWord *nextAddr, *lastAddr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4694 for (cumNumDirtyCards = numDirtyCards = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
4695 nextAddr = lastAddr = startAddr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4696 nextAddr < endAddr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4697 nextAddr = lastAddr, cumNumDirtyCards += numDirtyCards) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4698
a61af66fc99e Initial load
duke
parents:
diff changeset
4699 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4700 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4701
a61af66fc99e Initial load
duke
parents:
diff changeset
4702 MemRegion dirtyRegion;
a61af66fc99e Initial load
duke
parents:
diff changeset
4703 {
a61af66fc99e Initial load
duke
parents:
diff changeset
4704 stopTimer();
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4705 // Potential yield point
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4706 CMSTokenSync ts(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4707 startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4708 sample_eden();
a61af66fc99e Initial load
duke
parents:
diff changeset
4709 // Get dirty region starting at nextOffset (inclusive),
a61af66fc99e Initial load
duke
parents:
diff changeset
4710 // simultaneously clearing it.
a61af66fc99e Initial load
duke
parents:
diff changeset
4711 dirtyRegion =
a61af66fc99e Initial load
duke
parents:
diff changeset
4712 _modUnionTable.getAndClearMarkedRegion(nextAddr, endAddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4713 assert(dirtyRegion.start() >= nextAddr,
a61af66fc99e Initial load
duke
parents:
diff changeset
4714 "returned region inconsistent?");
a61af66fc99e Initial load
duke
parents:
diff changeset
4715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4716 // Remember where the next search should begin.
a61af66fc99e Initial load
duke
parents:
diff changeset
4717 // The returned region (if non-empty) is a right open interval,
a61af66fc99e Initial load
duke
parents:
diff changeset
4718 // so lastOffset is obtained from the right end of that
a61af66fc99e Initial load
duke
parents:
diff changeset
4719 // interval.
a61af66fc99e Initial load
duke
parents:
diff changeset
4720 lastAddr = dirtyRegion.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
4721 // Should do something more transparent and less hacky XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
4722 numDirtyCards =
a61af66fc99e Initial load
duke
parents:
diff changeset
4723 _modUnionTable.heapWordDiffToOffsetDiff(dirtyRegion.word_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
4724
a61af66fc99e Initial load
duke
parents:
diff changeset
4725 // We'll scan the cards in the dirty region (with periodic
a61af66fc99e Initial load
duke
parents:
diff changeset
4726 // yields for foreground GC as needed).
a61af66fc99e Initial load
duke
parents:
diff changeset
4727 if (!dirtyRegion.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4728 assert(numDirtyCards > 0, "consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
4729 HeapWord* stop_point = NULL;
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
4730 stopTimer();
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
4731 // Potential yield point
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
4732 CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
4733 bitMapLock());
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
4734 startTimer();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4735 {
a61af66fc99e Initial load
duke
parents:
diff changeset
4736 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4737 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4738 sample_eden();
1190
4788266644c1 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 1145
diff changeset
4739 DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4740 stop_point =
a61af66fc99e Initial load
duke
parents:
diff changeset
4741 gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4743 if (stop_point != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4744 // The careful iteration stopped early either because it found an
a61af66fc99e Initial load
duke
parents:
diff changeset
4745 // uninitialized object, or because we were in the midst of an
a61af66fc99e Initial load
duke
parents:
diff changeset
4746 // "abortable preclean", which should now be aborted. Redirty
a61af66fc99e Initial load
duke
parents:
diff changeset
4747 // the bits corresponding to the partially-scanned or unscanned
a61af66fc99e Initial load
duke
parents:
diff changeset
4748 // cards. We'll either restart at the next block boundary or
a61af66fc99e Initial load
duke
parents:
diff changeset
4749 // abort the preclean.
a61af66fc99e Initial load
duke
parents:
diff changeset
4750 assert((CMSPermGenPrecleaningEnabled && (gen == _permGen)) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4751 (_collectorState == AbortablePreclean && should_abort_preclean()),
a61af66fc99e Initial load
duke
parents:
diff changeset
4752 "Unparsable objects should only be in perm gen.");
a61af66fc99e Initial load
duke
parents:
diff changeset
4753 _modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end()));
a61af66fc99e Initial load
duke
parents:
diff changeset
4754 if (should_abort_preclean()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4755 break; // out of preclean loop
a61af66fc99e Initial load
duke
parents:
diff changeset
4756 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4757 // Compute the next address at which preclean should pick up;
a61af66fc99e Initial load
duke
parents:
diff changeset
4758 // might need bitMapLock in order to read P-bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
4759 lastAddr = next_card_start_after_block(stop_point);
a61af66fc99e Initial load
duke
parents:
diff changeset
4760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4761 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4762 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4763 assert(lastAddr == endAddr, "consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
4764 assert(numDirtyCards == 0, "consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
4765 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4768 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4769 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4770 return cumNumDirtyCards;
a61af66fc99e Initial load
duke
parents:
diff changeset
4771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4772
a61af66fc99e Initial load
duke
parents:
diff changeset
4773 // NOTE: preclean_mod_union_table() above and preclean_card_table()
a61af66fc99e Initial load
duke
parents:
diff changeset
4774 // below are largely identical; if you need to modify
a61af66fc99e Initial load
duke
parents:
diff changeset
4775 // one of these methods, please check the other method too.
a61af66fc99e Initial load
duke
parents:
diff changeset
4776
a61af66fc99e Initial load
duke
parents:
diff changeset
4777 size_t CMSCollector::preclean_card_table(ConcurrentMarkSweepGeneration* gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
4778 ScanMarkedObjectsAgainCarefullyClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4779 // strategy: it's similar to precleamModUnionTable above, in that
a61af66fc99e Initial load
duke
parents:
diff changeset
4780 // we accumulate contiguous ranges of dirty cards, mark these cards
a61af66fc99e Initial load
duke
parents:
diff changeset
4781 // precleaned, then scan the region covered by these cards.
a61af66fc99e Initial load
duke
parents:
diff changeset
4782 HeapWord* endAddr = (HeapWord*)(gen->_virtual_space.high());
a61af66fc99e Initial load
duke
parents:
diff changeset
4783 HeapWord* startAddr = (HeapWord*)(gen->_virtual_space.low());
a61af66fc99e Initial load
duke
parents:
diff changeset
4784
a61af66fc99e Initial load
duke
parents:
diff changeset
4785 cl->setFreelistLock(gen->freelistLock()); // needed for yielding
a61af66fc99e Initial load
duke
parents:
diff changeset
4786
a61af66fc99e Initial load
duke
parents:
diff changeset
4787 size_t numDirtyCards, cumNumDirtyCards;
a61af66fc99e Initial load
duke
parents:
diff changeset
4788 HeapWord *lastAddr, *nextAddr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4789
a61af66fc99e Initial load
duke
parents:
diff changeset
4790 for (cumNumDirtyCards = numDirtyCards = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
4791 nextAddr = lastAddr = startAddr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4792 nextAddr < endAddr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4793 nextAddr = lastAddr, cumNumDirtyCards += numDirtyCards) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4794
a61af66fc99e Initial load
duke
parents:
diff changeset
4795 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4796 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4797
a61af66fc99e Initial load
duke
parents:
diff changeset
4798 MemRegion dirtyRegion;
a61af66fc99e Initial load
duke
parents:
diff changeset
4799 {
a61af66fc99e Initial load
duke
parents:
diff changeset
4800 // See comments in "Precleaning notes" above on why we
a61af66fc99e Initial load
duke
parents:
diff changeset
4801 // do this locking. XXX Could the locking overheads be
a61af66fc99e Initial load
duke
parents:
diff changeset
4802 // too high when dirty cards are sparse? [I don't think so.]
a61af66fc99e Initial load
duke
parents:
diff changeset
4803 stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4804 CMSTokenSync x(true); // is cms thread
a61af66fc99e Initial load
duke
parents:
diff changeset
4805 startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4806 sample_eden();
a61af66fc99e Initial load
duke
parents:
diff changeset
4807 // Get and clear dirty region from card table
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
4808 dirtyRegion = _ct->ct_bs()->dirty_card_range_after_reset(
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
4809 MemRegion(nextAddr, endAddr),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
4810 true,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
4811 CardTableModRefBS::precleaned_card_val());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
4812
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4813 assert(dirtyRegion.start() >= nextAddr,
a61af66fc99e Initial load
duke
parents:
diff changeset
4814 "returned region inconsistent?");
a61af66fc99e Initial load
duke
parents:
diff changeset
4815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4816 lastAddr = dirtyRegion.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
4817 numDirtyCards =
a61af66fc99e Initial load
duke
parents:
diff changeset
4818 dirtyRegion.word_size()/CardTableModRefBS::card_size_in_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
4819
a61af66fc99e Initial load
duke
parents:
diff changeset
4820 if (!dirtyRegion.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4821 stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4822 CMSTokenSyncWithLocks ts(true, gen->freelistLock(), bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
4823 startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
4824 sample_eden();
a61af66fc99e Initial load
duke
parents:
diff changeset
4825 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4826 verify_overflow_empty();
1190
4788266644c1 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 1145
diff changeset
4827 DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4828 HeapWord* stop_point =
a61af66fc99e Initial load
duke
parents:
diff changeset
4829 gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
4830 if (stop_point != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4831 // The careful iteration stopped early because it found an
a61af66fc99e Initial load
duke
parents:
diff changeset
4832 // uninitialized object. Redirty the bits corresponding to the
a61af66fc99e Initial load
duke
parents:
diff changeset
4833 // partially-scanned or unscanned cards, and start again at the
a61af66fc99e Initial load
duke
parents:
diff changeset
4834 // next block boundary.
a61af66fc99e Initial load
duke
parents:
diff changeset
4835 assert(CMSPermGenPrecleaningEnabled ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4836 (_collectorState == AbortablePreclean && should_abort_preclean()),
a61af66fc99e Initial load
duke
parents:
diff changeset
4837 "Unparsable objects should only be in perm gen.");
a61af66fc99e Initial load
duke
parents:
diff changeset
4838 _ct->ct_bs()->invalidate(MemRegion(stop_point, dirtyRegion.end()));
a61af66fc99e Initial load
duke
parents:
diff changeset
4839 if (should_abort_preclean()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4840 break; // out of preclean loop
a61af66fc99e Initial load
duke
parents:
diff changeset
4841 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4842 // Compute the next address at which preclean should pick up.
a61af66fc99e Initial load
duke
parents:
diff changeset
4843 lastAddr = next_card_start_after_block(stop_point);
a61af66fc99e Initial load
duke
parents:
diff changeset
4844 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4846 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4847 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4849 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4850 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4851 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4852 return cumNumDirtyCards;
a61af66fc99e Initial load
duke
parents:
diff changeset
4853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4854
a61af66fc99e Initial load
duke
parents:
diff changeset
4855 void CMSCollector::checkpointRootsFinal(bool asynch,
a61af66fc99e Initial load
duke
parents:
diff changeset
4856 bool clear_all_soft_refs, bool init_mark_was_synchronous) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4857 assert(_collectorState == FinalMarking, "incorrect state transition?");
a61af66fc99e Initial load
duke
parents:
diff changeset
4858 check_correct_thread_executing();
a61af66fc99e Initial load
duke
parents:
diff changeset
4859 // world is stopped at this checkpoint
a61af66fc99e Initial load
duke
parents:
diff changeset
4860 assert(SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4861 "world should be stopped");
1703
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
4862 TraceCMSMemoryManagerStats tms(_collectorState);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4863 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4864 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4865
a61af66fc99e Initial load
duke
parents:
diff changeset
4866 SpecializationStats::clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
4867 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4868 gclog_or_tty->print("[YG occupancy: "SIZE_FORMAT" K ("SIZE_FORMAT" K)]",
a61af66fc99e Initial load
duke
parents:
diff changeset
4869 _young_gen->used() / K,
a61af66fc99e Initial load
duke
parents:
diff changeset
4870 _young_gen->capacity() / K);
a61af66fc99e Initial load
duke
parents:
diff changeset
4871 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4872 if (asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4873 if (CMSScavengeBeforeRemark) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4874 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
4875 // Temporarily set flag to false, GCH->do_collection will
a61af66fc99e Initial load
duke
parents:
diff changeset
4876 // expect it to be false and set to true
a61af66fc99e Initial load
duke
parents:
diff changeset
4877 FlagSetting fl(gch->_is_gc_active, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4878 NOT_PRODUCT(TraceTime t("Scavenge-Before-Remark",
a61af66fc99e Initial load
duke
parents:
diff changeset
4879 PrintGCDetails && Verbose, true, gclog_or_tty);)
a61af66fc99e Initial load
duke
parents:
diff changeset
4880 int level = _cmsGen->level() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4881 if (level >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4882 gch->do_collection(true, // full (i.e. force, see below)
a61af66fc99e Initial load
duke
parents:
diff changeset
4883 false, // !clear_all_soft_refs
a61af66fc99e Initial load
duke
parents:
diff changeset
4884 0, // size
a61af66fc99e Initial load
duke
parents:
diff changeset
4885 false, // is_tlab
a61af66fc99e Initial load
duke
parents:
diff changeset
4886 level // max_level
a61af66fc99e Initial load
duke
parents:
diff changeset
4887 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4888 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4889 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4890 FreelistLocker x(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
4891 MutexLockerEx y(bitMapLock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4892 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
4893 assert(!init_mark_was_synchronous, "but that's impossible!");
a61af66fc99e Initial load
duke
parents:
diff changeset
4894 checkpointRootsFinalWork(asynch, clear_all_soft_refs, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4895 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4896 // already have all the locks
a61af66fc99e Initial load
duke
parents:
diff changeset
4897 checkpointRootsFinalWork(asynch, clear_all_soft_refs,
a61af66fc99e Initial load
duke
parents:
diff changeset
4898 init_mark_was_synchronous);
a61af66fc99e Initial load
duke
parents:
diff changeset
4899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4900 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4901 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4902 SpecializationStats::print();
a61af66fc99e Initial load
duke
parents:
diff changeset
4903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4904
a61af66fc99e Initial load
duke
parents:
diff changeset
4905 void CMSCollector::checkpointRootsFinalWork(bool asynch,
a61af66fc99e Initial load
duke
parents:
diff changeset
4906 bool clear_all_soft_refs, bool init_mark_was_synchronous) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4907
a61af66fc99e Initial load
duke
parents:
diff changeset
4908 NOT_PRODUCT(TraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, gclog_or_tty);)
a61af66fc99e Initial load
duke
parents:
diff changeset
4909
a61af66fc99e Initial load
duke
parents:
diff changeset
4910 assert(haveFreelistLocks(), "must have free list locks");
a61af66fc99e Initial load
duke
parents:
diff changeset
4911 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
4912
a61af66fc99e Initial load
duke
parents:
diff changeset
4913 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4914 size_policy()->checkpoint_roots_final_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
4915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4916
a61af66fc99e Initial load
duke
parents:
diff changeset
4917 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4918 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4919
a61af66fc99e Initial load
duke
parents:
diff changeset
4920 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
4921
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
4922 if (should_unload_classes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4923 CodeCache::gc_prologue();
a61af66fc99e Initial load
duke
parents:
diff changeset
4924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4925 assert(haveFreelistLocks(), "must have free list locks");
a61af66fc99e Initial load
duke
parents:
diff changeset
4926 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
4927
1190
4788266644c1 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 1145
diff changeset
4928 DEBUG_ONLY(RememberKlassesChecker fmx(should_unload_classes());)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4929 if (!init_mark_was_synchronous) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4930 // We might assume that we need not fill TLAB's when
a61af66fc99e Initial load
duke
parents:
diff changeset
4931 // CMSScavengeBeforeRemark is set, because we may have just done
a61af66fc99e Initial load
duke
parents:
diff changeset
4932 // a scavenge which would have filled all TLAB's -- and besides
a61af66fc99e Initial load
duke
parents:
diff changeset
4933 // Eden would be empty. This however may not always be the case --
a61af66fc99e Initial load
duke
parents:
diff changeset
4934 // for instance although we asked for a scavenge, it may not have
a61af66fc99e Initial load
duke
parents:
diff changeset
4935 // happened because of a JNI critical section. We probably need
a61af66fc99e Initial load
duke
parents:
diff changeset
4936 // a policy for deciding whether we can in that case wait until
a61af66fc99e Initial load
duke
parents:
diff changeset
4937 // the critical section releases and then do the remark following
a61af66fc99e Initial load
duke
parents:
diff changeset
4938 // the scavenge, and skip it here. In the absence of that policy,
a61af66fc99e Initial load
duke
parents:
diff changeset
4939 // or of an indication of whether the scavenge did indeed occur,
a61af66fc99e Initial load
duke
parents:
diff changeset
4940 // we cannot rely on TLAB's having been filled and must do
a61af66fc99e Initial load
duke
parents:
diff changeset
4941 // so here just in case a scavenge did not happen.
a61af66fc99e Initial load
duke
parents:
diff changeset
4942 gch->ensure_parsability(false); // fill TLAB's, but no need to retire them
a61af66fc99e Initial load
duke
parents:
diff changeset
4943 // Update the saved marks which may affect the root scans.
a61af66fc99e Initial load
duke
parents:
diff changeset
4944 gch->save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
4945
a61af66fc99e Initial load
duke
parents:
diff changeset
4946 {
a61af66fc99e Initial load
duke
parents:
diff changeset
4947 COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
a61af66fc99e Initial load
duke
parents:
diff changeset
4948
a61af66fc99e Initial load
duke
parents:
diff changeset
4949 // Note on the role of the mod union table:
a61af66fc99e Initial load
duke
parents:
diff changeset
4950 // Since the marker in "markFromRoots" marks concurrently with
a61af66fc99e Initial load
duke
parents:
diff changeset
4951 // mutators, it is possible for some reachable objects not to have been
a61af66fc99e Initial load
duke
parents:
diff changeset
4952 // scanned. For instance, an only reference to an object A was
a61af66fc99e Initial load
duke
parents:
diff changeset
4953 // placed in object B after the marker scanned B. Unless B is rescanned,
a61af66fc99e Initial load
duke
parents:
diff changeset
4954 // A would be collected. Such updates to references in marked objects
a61af66fc99e Initial load
duke
parents:
diff changeset
4955 // are detected via the mod union table which is the set of all cards
a61af66fc99e Initial load
duke
parents:
diff changeset
4956 // dirtied since the first checkpoint in this GC cycle and prior to
a61af66fc99e Initial load
duke
parents:
diff changeset
4957 // the most recent young generation GC, minus those cleaned up by the
a61af66fc99e Initial load
duke
parents:
diff changeset
4958 // concurrent precleaning.
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
4959 if (CMSParallelRemarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4960 TraceTime t("Rescan (parallel) ", PrintGCDetails, false, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
4961 do_remark_parallel();
a61af66fc99e Initial load
duke
parents:
diff changeset
4962 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4963 TraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
a61af66fc99e Initial load
duke
parents:
diff changeset
4964 gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
4965 do_remark_non_parallel();
a61af66fc99e Initial load
duke
parents:
diff changeset
4966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4967 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4968 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4969 assert(!asynch, "Can't have init_mark_was_synchronous in asynch mode");
a61af66fc99e Initial load
duke
parents:
diff changeset
4970 // The initial mark was stop-world, so there's no rescanning to
a61af66fc99e Initial load
duke
parents:
diff changeset
4971 // do; go straight on to the next step below.
a61af66fc99e Initial load
duke
parents:
diff changeset
4972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4973 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4974 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4975
a61af66fc99e Initial load
duke
parents:
diff changeset
4976 {
a61af66fc99e Initial load
duke
parents:
diff changeset
4977 NOT_PRODUCT(TraceTime ts("refProcessingWork", PrintGCDetails, false, gclog_or_tty);)
a61af66fc99e Initial load
duke
parents:
diff changeset
4978 refProcessingWork(asynch, clear_all_soft_refs);
a61af66fc99e Initial load
duke
parents:
diff changeset
4979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4980 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4981 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
4982
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
4983 if (should_unload_classes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4984 CodeCache::gc_epilogue();
a61af66fc99e Initial load
duke
parents:
diff changeset
4985 }
2147
9afee0b9fc1d 7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents: 2137
diff changeset
4986 JvmtiExport::gc_epilogue();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4987
a61af66fc99e Initial load
duke
parents:
diff changeset
4988 // If we encountered any (marking stack / work queue) overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
4989 // events during the current CMS cycle, take appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
4990 // remedial measures, where possible, so as to try and avoid
a61af66fc99e Initial load
duke
parents:
diff changeset
4991 // recurrence of that condition.
a61af66fc99e Initial load
duke
parents:
diff changeset
4992 assert(_markStack.isEmpty(), "No grey objects");
a61af66fc99e Initial load
duke
parents:
diff changeset
4993 size_t ser_ovflw = _ser_pmc_remark_ovflw + _ser_pmc_preclean_ovflw +
452
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
4994 _ser_kac_ovflw + _ser_kac_preclean_ovflw;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4995 if (ser_ovflw > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4996 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4997 gclog_or_tty->print_cr("Marking stack overflow (benign) "
452
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
4998 "(pmc_pc="SIZE_FORMAT", pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
4999 ", kac_preclean="SIZE_FORMAT")",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5000 _ser_pmc_preclean_ovflw, _ser_pmc_remark_ovflw,
452
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
5001 _ser_kac_ovflw, _ser_kac_preclean_ovflw);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5003 _markStack.expand();
a61af66fc99e Initial load
duke
parents:
diff changeset
5004 _ser_pmc_remark_ovflw = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5005 _ser_pmc_preclean_ovflw = 0;
452
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
5006 _ser_kac_preclean_ovflw = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5007 _ser_kac_ovflw = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5009 if (_par_pmc_remark_ovflw > 0 || _par_kac_ovflw > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5010 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5011 gclog_or_tty->print_cr("Work queue overflow (benign) "
a61af66fc99e Initial load
duke
parents:
diff changeset
5012 "(pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT")",
a61af66fc99e Initial load
duke
parents:
diff changeset
5013 _par_pmc_remark_ovflw, _par_kac_ovflw);
a61af66fc99e Initial load
duke
parents:
diff changeset
5014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5015 _par_pmc_remark_ovflw = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5016 _par_kac_ovflw = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5018 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5019 if (_markStack._hit_limit > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5020 gclog_or_tty->print_cr(" (benign) Hit max stack size limit ("SIZE_FORMAT")",
a61af66fc99e Initial load
duke
parents:
diff changeset
5021 _markStack._hit_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
5022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5023 if (_markStack._failed_double > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5024 gclog_or_tty->print_cr(" (benign) Failed stack doubling ("SIZE_FORMAT"),"
a61af66fc99e Initial load
duke
parents:
diff changeset
5025 " current capacity "SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
5026 _markStack._failed_double,
a61af66fc99e Initial load
duke
parents:
diff changeset
5027 _markStack.capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
5028 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5030 _markStack._hit_limit = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5031 _markStack._failed_double = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5032
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5033 // Check that all the klasses have been checked
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5034 assert(_revisitStack.isEmpty(), "Not all klasses revisited");
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5035
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5036 if ((VerifyAfterGC || VerifyDuringGC) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
5037 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5038 verify_after_remark();
a61af66fc99e Initial load
duke
parents:
diff changeset
5039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5040
a61af66fc99e Initial load
duke
parents:
diff changeset
5041 // Change under the freelistLocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
5042 _collectorState = Sweeping;
a61af66fc99e Initial load
duke
parents:
diff changeset
5043 // Call isAllClear() under bitMapLock
a61af66fc99e Initial load
duke
parents:
diff changeset
5044 assert(_modUnionTable.isAllClear(), "Should be clear by end of the"
a61af66fc99e Initial load
duke
parents:
diff changeset
5045 " final marking");
a61af66fc99e Initial load
duke
parents:
diff changeset
5046 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5047 size_policy()->checkpoint_roots_final_end(gch->gc_cause());
a61af66fc99e Initial load
duke
parents:
diff changeset
5048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5050
a61af66fc99e Initial load
duke
parents:
diff changeset
5051 // Parallel remark task
a61af66fc99e Initial load
duke
parents:
diff changeset
5052 class CMSParRemarkTask: public AbstractGangTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
5053 CMSCollector* _collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
5054 int _n_workers;
a61af66fc99e Initial load
duke
parents:
diff changeset
5055 CompactibleFreeListSpace* _cms_space;
a61af66fc99e Initial load
duke
parents:
diff changeset
5056 CompactibleFreeListSpace* _perm_space;
a61af66fc99e Initial load
duke
parents:
diff changeset
5057
a61af66fc99e Initial load
duke
parents:
diff changeset
5058 // The per-thread work queues, available here for stealing.
a61af66fc99e Initial load
duke
parents:
diff changeset
5059 OopTaskQueueSet* _task_queues;
a61af66fc99e Initial load
duke
parents:
diff changeset
5060 ParallelTaskTerminator _term;
a61af66fc99e Initial load
duke
parents:
diff changeset
5061
a61af66fc99e Initial load
duke
parents:
diff changeset
5062 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
5063 CMSParRemarkTask(CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
5064 CompactibleFreeListSpace* cms_space,
a61af66fc99e Initial load
duke
parents:
diff changeset
5065 CompactibleFreeListSpace* perm_space,
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5066 int n_workers, FlexibleWorkGang* workers,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5067 OopTaskQueueSet* task_queues):
a61af66fc99e Initial load
duke
parents:
diff changeset
5068 AbstractGangTask("Rescan roots and grey objects in parallel"),
a61af66fc99e Initial load
duke
parents:
diff changeset
5069 _collector(collector),
a61af66fc99e Initial load
duke
parents:
diff changeset
5070 _cms_space(cms_space), _perm_space(perm_space),
a61af66fc99e Initial load
duke
parents:
diff changeset
5071 _n_workers(n_workers),
a61af66fc99e Initial load
duke
parents:
diff changeset
5072 _task_queues(task_queues),
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5073 _term(n_workers, task_queues) { }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5074
a61af66fc99e Initial load
duke
parents:
diff changeset
5075 OopTaskQueueSet* task_queues() { return _task_queues; }
a61af66fc99e Initial load
duke
parents:
diff changeset
5076
a61af66fc99e Initial load
duke
parents:
diff changeset
5077 OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
a61af66fc99e Initial load
duke
parents:
diff changeset
5078
a61af66fc99e Initial load
duke
parents:
diff changeset
5079 ParallelTaskTerminator* terminator() { return &_term; }
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5080 int n_workers() { return _n_workers; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5081
a61af66fc99e Initial load
duke
parents:
diff changeset
5082 void work(int i);
a61af66fc99e Initial load
duke
parents:
diff changeset
5083
a61af66fc99e Initial load
duke
parents:
diff changeset
5084 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
5085 // Work method in support of parallel rescan ... of young gen spaces
a61af66fc99e Initial load
duke
parents:
diff changeset
5086 void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
5087 ContiguousSpace* space,
a61af66fc99e Initial load
duke
parents:
diff changeset
5088 HeapWord** chunk_array, size_t chunk_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
5089
a61af66fc99e Initial load
duke
parents:
diff changeset
5090 // ... of dirty cards in old space
a61af66fc99e Initial load
duke
parents:
diff changeset
5091 void do_dirty_card_rescan_tasks(CompactibleFreeListSpace* sp, int i,
a61af66fc99e Initial load
duke
parents:
diff changeset
5092 Par_MarkRefsIntoAndScanClosure* cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5093
a61af66fc99e Initial load
duke
parents:
diff changeset
5094 // ... work stealing for the above
a61af66fc99e Initial load
duke
parents:
diff changeset
5095 void do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl, int* seed);
a61af66fc99e Initial load
duke
parents:
diff changeset
5096 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5097
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5098 // work_queue(i) is passed to the closure
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5099 // Par_MarkRefsIntoAndScanClosure. The "i" parameter
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5100 // also is passed to do_dirty_card_rescan_tasks() and to
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5101 // do_work_steal() to select the i-th task_queue.
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5102
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5103 void CMSParRemarkTask::work(int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5104 elapsedTimer _timer;
a61af66fc99e Initial load
duke
parents:
diff changeset
5105 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
5106 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
5107
a61af66fc99e Initial load
duke
parents:
diff changeset
5108 // ---------- rescan from roots --------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5109 _timer.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
5110 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
5111 Par_MarkRefsIntoAndScanClosure par_mrias_cl(_collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
5112 _collector->_span, _collector->ref_processor(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5113 &(_collector->_markBitMap),
a61af66fc99e Initial load
duke
parents:
diff changeset
5114 work_queue(i), &(_collector->_revisitStack));
a61af66fc99e Initial load
duke
parents:
diff changeset
5115
a61af66fc99e Initial load
duke
parents:
diff changeset
5116 // Rescan young gen roots first since these are likely
a61af66fc99e Initial load
duke
parents:
diff changeset
5117 // coarsely partitioned and may, on that account, constitute
a61af66fc99e Initial load
duke
parents:
diff changeset
5118 // the critical path; thus, it's best to start off that
a61af66fc99e Initial load
duke
parents:
diff changeset
5119 // work first.
a61af66fc99e Initial load
duke
parents:
diff changeset
5120 // ---------- young gen roots --------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5121 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5122 DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
a61af66fc99e Initial load
duke
parents:
diff changeset
5123 EdenSpace* eden_space = dng->eden();
a61af66fc99e Initial load
duke
parents:
diff changeset
5124 ContiguousSpace* from_space = dng->from();
a61af66fc99e Initial load
duke
parents:
diff changeset
5125 ContiguousSpace* to_space = dng->to();
a61af66fc99e Initial load
duke
parents:
diff changeset
5126
a61af66fc99e Initial load
duke
parents:
diff changeset
5127 HeapWord** eca = _collector->_eden_chunk_array;
a61af66fc99e Initial load
duke
parents:
diff changeset
5128 size_t ect = _collector->_eden_chunk_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
5129 HeapWord** sca = _collector->_survivor_chunk_array;
a61af66fc99e Initial load
duke
parents:
diff changeset
5130 size_t sct = _collector->_survivor_chunk_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
5131
a61af66fc99e Initial load
duke
parents:
diff changeset
5132 assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
5133 assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
5134
a61af66fc99e Initial load
duke
parents:
diff changeset
5135 do_young_space_rescan(i, &par_mrias_cl, to_space, NULL, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5136 do_young_space_rescan(i, &par_mrias_cl, from_space, sca, sct);
a61af66fc99e Initial load
duke
parents:
diff changeset
5137 do_young_space_rescan(i, &par_mrias_cl, eden_space, eca, ect);
a61af66fc99e Initial load
duke
parents:
diff changeset
5138
a61af66fc99e Initial load
duke
parents:
diff changeset
5139 _timer.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
5140 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5141 gclog_or_tty->print_cr(
a61af66fc99e Initial load
duke
parents:
diff changeset
5142 "Finished young gen rescan work in %dth thread: %3.3f sec",
a61af66fc99e Initial load
duke
parents:
diff changeset
5143 i, _timer.seconds());
a61af66fc99e Initial load
duke
parents:
diff changeset
5144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5146
a61af66fc99e Initial load
duke
parents:
diff changeset
5147 // ---------- remaining roots --------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5148 _timer.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
5149 _timer.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
5150 gch->gen_process_strong_roots(_collector->_cmsGen->level(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5151 false, // yg was scanned above
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5152 false, // this is parallel code
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5153 true, // collecting perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
5154 SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5155 &par_mrias_cl,
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5156 true, // walk all of code cache if (so & SO_CodeCache)
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5157 NULL);
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5158 assert(_collector->should_unload_classes()
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5159 || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5160 "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5161 _timer.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
5162 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5163 gclog_or_tty->print_cr(
a61af66fc99e Initial load
duke
parents:
diff changeset
5164 "Finished remaining root rescan work in %dth thread: %3.3f sec",
a61af66fc99e Initial load
duke
parents:
diff changeset
5165 i, _timer.seconds());
a61af66fc99e Initial load
duke
parents:
diff changeset
5166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5167
a61af66fc99e Initial load
duke
parents:
diff changeset
5168 // ---------- rescan dirty cards ------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5169 _timer.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
5170 _timer.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
5171
a61af66fc99e Initial load
duke
parents:
diff changeset
5172 // Do the rescan tasks for each of the two spaces
a61af66fc99e Initial load
duke
parents:
diff changeset
5173 // (cms_space and perm_space) in turn.
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5174 // "i" is passed to select the "i-th" task_queue
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5175 do_dirty_card_rescan_tasks(_cms_space, i, &par_mrias_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5176 do_dirty_card_rescan_tasks(_perm_space, i, &par_mrias_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5177 _timer.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
5178 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5179 gclog_or_tty->print_cr(
a61af66fc99e Initial load
duke
parents:
diff changeset
5180 "Finished dirty card rescan work in %dth thread: %3.3f sec",
a61af66fc99e Initial load
duke
parents:
diff changeset
5181 i, _timer.seconds());
a61af66fc99e Initial load
duke
parents:
diff changeset
5182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5183
a61af66fc99e Initial load
duke
parents:
diff changeset
5184 // ---------- steal work from other threads ...
a61af66fc99e Initial load
duke
parents:
diff changeset
5185 // ---------- ... and drain overflow list.
a61af66fc99e Initial load
duke
parents:
diff changeset
5186 _timer.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
5187 _timer.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
5188 do_work_steal(i, &par_mrias_cl, _collector->hash_seed(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
5189 _timer.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
5190 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5191 gclog_or_tty->print_cr(
a61af66fc99e Initial load
duke
parents:
diff changeset
5192 "Finished work stealing in %dth thread: %3.3f sec",
a61af66fc99e Initial load
duke
parents:
diff changeset
5193 i, _timer.seconds());
a61af66fc99e Initial load
duke
parents:
diff changeset
5194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5196
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5197 // Note that parameter "i" is not used.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5198 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5199 CMSParRemarkTask::do_young_space_rescan(int i,
a61af66fc99e Initial load
duke
parents:
diff changeset
5200 Par_MarkRefsIntoAndScanClosure* cl, ContiguousSpace* space,
a61af66fc99e Initial load
duke
parents:
diff changeset
5201 HeapWord** chunk_array, size_t chunk_top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5202 // Until all tasks completed:
a61af66fc99e Initial load
duke
parents:
diff changeset
5203 // . claim an unclaimed task
a61af66fc99e Initial load
duke
parents:
diff changeset
5204 // . compute region boundaries corresponding to task claimed
a61af66fc99e Initial load
duke
parents:
diff changeset
5205 // using chunk_array
a61af66fc99e Initial load
duke
parents:
diff changeset
5206 // . par_oop_iterate(cl) over that region
a61af66fc99e Initial load
duke
parents:
diff changeset
5207
a61af66fc99e Initial load
duke
parents:
diff changeset
5208 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
5209 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
5210
a61af66fc99e Initial load
duke
parents:
diff changeset
5211 SequentialSubTasksDone* pst = space->par_seq_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
5212 assert(pst->valid(), "Uninitialized use?");
a61af66fc99e Initial load
duke
parents:
diff changeset
5213
a61af66fc99e Initial load
duke
parents:
diff changeset
5214 int nth_task = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5215 int n_tasks = pst->n_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
5216
a61af66fc99e Initial load
duke
parents:
diff changeset
5217 HeapWord *start, *end;
a61af66fc99e Initial load
duke
parents:
diff changeset
5218 while (!pst->is_task_claimed(/* reference */ nth_task)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5219 // We claimed task # nth_task; compute its boundaries.
a61af66fc99e Initial load
duke
parents:
diff changeset
5220 if (chunk_top == 0) { // no samples were taken
a61af66fc99e Initial load
duke
parents:
diff changeset
5221 assert(nth_task == 0 && n_tasks == 1, "Can have only 1 EdenSpace task");
a61af66fc99e Initial load
duke
parents:
diff changeset
5222 start = space->bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
5223 end = space->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
5224 } else if (nth_task == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5225 start = space->bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
5226 end = chunk_array[nth_task];
a61af66fc99e Initial load
duke
parents:
diff changeset
5227 } else if (nth_task < (jint)chunk_top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5228 assert(nth_task >= 1, "Control point invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
5229 start = chunk_array[nth_task - 1];
a61af66fc99e Initial load
duke
parents:
diff changeset
5230 end = chunk_array[nth_task];
a61af66fc99e Initial load
duke
parents:
diff changeset
5231 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5232 assert(nth_task == (jint)chunk_top, "Control point invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
5233 start = chunk_array[chunk_top - 1];
a61af66fc99e Initial load
duke
parents:
diff changeset
5234 end = space->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
5235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5236 MemRegion mr(start, end);
a61af66fc99e Initial load
duke
parents:
diff changeset
5237 // Verify that mr is in space
a61af66fc99e Initial load
duke
parents:
diff changeset
5238 assert(mr.is_empty() || space->used_region().contains(mr),
a61af66fc99e Initial load
duke
parents:
diff changeset
5239 "Should be in space");
a61af66fc99e Initial load
duke
parents:
diff changeset
5240 // Verify that "start" is an object boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
5241 assert(mr.is_empty() || oop(mr.start())->is_oop(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5242 "Should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
5243 space->par_oop_iterate(mr, cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5245 pst->all_tasks_completed();
a61af66fc99e Initial load
duke
parents:
diff changeset
5246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5247
a61af66fc99e Initial load
duke
parents:
diff changeset
5248 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5249 CMSParRemarkTask::do_dirty_card_rescan_tasks(
a61af66fc99e Initial load
duke
parents:
diff changeset
5250 CompactibleFreeListSpace* sp, int i,
a61af66fc99e Initial load
duke
parents:
diff changeset
5251 Par_MarkRefsIntoAndScanClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5252 // Until all tasks completed:
a61af66fc99e Initial load
duke
parents:
diff changeset
5253 // . claim an unclaimed task
a61af66fc99e Initial load
duke
parents:
diff changeset
5254 // . compute region boundaries corresponding to task claimed
a61af66fc99e Initial load
duke
parents:
diff changeset
5255 // . transfer dirty bits ct->mut for that region
a61af66fc99e Initial load
duke
parents:
diff changeset
5256 // . apply rescanclosure to dirty mut bits for that region
a61af66fc99e Initial load
duke
parents:
diff changeset
5257
a61af66fc99e Initial load
duke
parents:
diff changeset
5258 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
5259 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
5260
a61af66fc99e Initial load
duke
parents:
diff changeset
5261 OopTaskQueue* work_q = work_queue(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
5262 ModUnionClosure modUnionClosure(&(_collector->_modUnionTable));
a61af66fc99e Initial load
duke
parents:
diff changeset
5263 // CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! CAUTION!
a61af66fc99e Initial load
duke
parents:
diff changeset
5264 // CAUTION: This closure has state that persists across calls to
a61af66fc99e Initial load
duke
parents:
diff changeset
5265 // the work method dirty_range_iterate_clear() in that it has
a61af66fc99e Initial load
duke
parents:
diff changeset
5266 // imbedded in it a (subtype of) UpwardsObjectClosure. The
a61af66fc99e Initial load
duke
parents:
diff changeset
5267 // use of that state in the imbedded UpwardsObjectClosure instance
a61af66fc99e Initial load
duke
parents:
diff changeset
5268 // assumes that the cards are always iterated (even if in parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
5269 // by several threads) in monotonically increasing order per each
a61af66fc99e Initial load
duke
parents:
diff changeset
5270 // thread. This is true of the implementation below which picks
a61af66fc99e Initial load
duke
parents:
diff changeset
5271 // card ranges (chunks) in monotonically increasing order globally
a61af66fc99e Initial load
duke
parents:
diff changeset
5272 // and, a-fortiori, in monotonically increasing order per thread
a61af66fc99e Initial load
duke
parents:
diff changeset
5273 // (the latter order being a subsequence of the former).
a61af66fc99e Initial load
duke
parents:
diff changeset
5274 // If the work code below is ever reorganized into a more chaotic
a61af66fc99e Initial load
duke
parents:
diff changeset
5275 // work-partitioning form than the current "sequential tasks"
a61af66fc99e Initial load
duke
parents:
diff changeset
5276 // paradigm, the use of that persistent state will have to be
a61af66fc99e Initial load
duke
parents:
diff changeset
5277 // revisited and modified appropriately. See also related
a61af66fc99e Initial load
duke
parents:
diff changeset
5278 // bug 4756801 work on which should examine this code to make
a61af66fc99e Initial load
duke
parents:
diff changeset
5279 // sure that the changes there do not run counter to the
a61af66fc99e Initial load
duke
parents:
diff changeset
5280 // assumptions made here and necessary for correctness and
a61af66fc99e Initial load
duke
parents:
diff changeset
5281 // efficiency. Note also that this code might yield inefficient
a61af66fc99e Initial load
duke
parents:
diff changeset
5282 // behaviour in the case of very large objects that span one or
a61af66fc99e Initial load
duke
parents:
diff changeset
5283 // more work chunks. Such objects would potentially be scanned
a61af66fc99e Initial load
duke
parents:
diff changeset
5284 // several times redundantly. Work on 4756801 should try and
a61af66fc99e Initial load
duke
parents:
diff changeset
5285 // address that performance anomaly if at all possible. XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
5286 MemRegion full_span = _collector->_span;
a61af66fc99e Initial load
duke
parents:
diff changeset
5287 CMSBitMap* bm = &(_collector->_markBitMap); // shared
a61af66fc99e Initial load
duke
parents:
diff changeset
5288 CMSMarkStack* rs = &(_collector->_revisitStack); // shared
a61af66fc99e Initial load
duke
parents:
diff changeset
5289 MarkFromDirtyCardsClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
5290 greyRescanClosure(_collector, full_span, // entire span of interest
a61af66fc99e Initial load
duke
parents:
diff changeset
5291 sp, bm, work_q, rs, cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5292
a61af66fc99e Initial load
duke
parents:
diff changeset
5293 SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
5294 assert(pst->valid(), "Uninitialized use?");
a61af66fc99e Initial load
duke
parents:
diff changeset
5295 int nth_task = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5296 const int alignment = CardTableModRefBS::card_size * BitsPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
5297 MemRegion span = sp->used_region();
a61af66fc99e Initial load
duke
parents:
diff changeset
5298 HeapWord* start_addr = span.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
5299 HeapWord* end_addr = (HeapWord*)round_to((intptr_t)span.end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5300 alignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
5301 const size_t chunk_size = sp->rescan_task_size(); // in HeapWord units
a61af66fc99e Initial load
duke
parents:
diff changeset
5302 assert((HeapWord*)round_to((intptr_t)start_addr, alignment) ==
a61af66fc99e Initial load
duke
parents:
diff changeset
5303 start_addr, "Check alignment");
a61af66fc99e Initial load
duke
parents:
diff changeset
5304 assert((size_t)round_to((intptr_t)chunk_size, alignment) ==
a61af66fc99e Initial load
duke
parents:
diff changeset
5305 chunk_size, "Check alignment");
a61af66fc99e Initial load
duke
parents:
diff changeset
5306
a61af66fc99e Initial load
duke
parents:
diff changeset
5307 while (!pst->is_task_claimed(/* reference */ nth_task)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5308 // Having claimed the nth_task, compute corresponding mem-region,
a61af66fc99e Initial load
duke
parents:
diff changeset
5309 // which is a-fortiori aligned correctly (i.e. at a MUT bopundary).
a61af66fc99e Initial load
duke
parents:
diff changeset
5310 // The alignment restriction ensures that we do not need any
a61af66fc99e Initial load
duke
parents:
diff changeset
5311 // synchronization with other gang-workers while setting or
a61af66fc99e Initial load
duke
parents:
diff changeset
5312 // clearing bits in thus chunk of the MUT.
a61af66fc99e Initial load
duke
parents:
diff changeset
5313 MemRegion this_span = MemRegion(start_addr + nth_task*chunk_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
5314 start_addr + (nth_task+1)*chunk_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
5315 // The last chunk's end might be way beyond end of the
a61af66fc99e Initial load
duke
parents:
diff changeset
5316 // used region. In that case pull back appropriately.
a61af66fc99e Initial load
duke
parents:
diff changeset
5317 if (this_span.end() > end_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5318 this_span.set_end(end_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
5319 assert(!this_span.is_empty(), "Program logic (calculation of n_tasks)");
a61af66fc99e Initial load
duke
parents:
diff changeset
5320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5321 // Iterate over the dirty cards covering this chunk, marking them
a61af66fc99e Initial load
duke
parents:
diff changeset
5322 // precleaned, and setting the corresponding bits in the mod union
a61af66fc99e Initial load
duke
parents:
diff changeset
5323 // table. Since we have been careful to partition at Card and MUT-word
a61af66fc99e Initial load
duke
parents:
diff changeset
5324 // boundaries no synchronization is needed between parallel threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
5325 _collector->_ct->ct_bs()->dirty_card_iterate(this_span,
a61af66fc99e Initial load
duke
parents:
diff changeset
5326 &modUnionClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
5327
a61af66fc99e Initial load
duke
parents:
diff changeset
5328 // Having transferred these marks into the modUnionTable,
a61af66fc99e Initial load
duke
parents:
diff changeset
5329 // rescan the marked objects on the dirty cards in the modUnionTable.
a61af66fc99e Initial load
duke
parents:
diff changeset
5330 // Even if this is at a synchronous collection, the initial marking
a61af66fc99e Initial load
duke
parents:
diff changeset
5331 // may have been done during an asynchronous collection so there
a61af66fc99e Initial load
duke
parents:
diff changeset
5332 // may be dirty bits in the mod-union table.
a61af66fc99e Initial load
duke
parents:
diff changeset
5333 _collector->_modUnionTable.dirty_range_iterate_clear(
a61af66fc99e Initial load
duke
parents:
diff changeset
5334 this_span, &greyRescanClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
5335 _collector->_modUnionTable.verifyNoOneBitsInRange(
a61af66fc99e Initial load
duke
parents:
diff changeset
5336 this_span.start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5337 this_span.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
5338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5339 pst->all_tasks_completed(); // declare that i am done
a61af66fc99e Initial load
duke
parents:
diff changeset
5340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5341
a61af66fc99e Initial load
duke
parents:
diff changeset
5342 // . see if we can share work_queues with ParNew? XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
5343 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5344 CMSParRemarkTask::do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
5345 int* seed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5346 OopTaskQueue* work_q = work_queue(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
5347 NOT_PRODUCT(int num_steals = 0;)
a61af66fc99e Initial load
duke
parents:
diff changeset
5348 oop obj_to_scan;
a61af66fc99e Initial load
duke
parents:
diff changeset
5349 CMSBitMap* bm = &(_collector->_markBitMap);
a61af66fc99e Initial load
duke
parents:
diff changeset
5350
a61af66fc99e Initial load
duke
parents:
diff changeset
5351 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5352 // Completely finish any left over work from (an) earlier round(s)
a61af66fc99e Initial load
duke
parents:
diff changeset
5353 cl->trim_queue(0);
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 628
diff changeset
5354 size_t num_from_overflow_list = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 628
diff changeset
5355 (size_t)ParGCDesiredObjsFromOverflowList);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5356 // Now check if there's any work in the overflow list
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5357 // Passing ParallelGCThreads as the third parameter, no_of_gc_threads,
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5358 // only affects the number of attempts made to get work from the
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5359 // overflow list and does not affect the number of workers. Just
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5360 // pass ParallelGCThreads so this behavior is unchanged.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5361 if (_collector->par_take_from_overflow_list(num_from_overflow_list,
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5362 work_q,
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5363 ParallelGCThreads)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5364 // found something in global overflow list;
a61af66fc99e Initial load
duke
parents:
diff changeset
5365 // not yet ready to go stealing work from others.
a61af66fc99e Initial load
duke
parents:
diff changeset
5366 // We'd like to assert(work_q->size() != 0, ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
5367 // because we just took work from the overflow list,
a61af66fc99e Initial load
duke
parents:
diff changeset
5368 // but of course we can't since all of that could have
a61af66fc99e Initial load
duke
parents:
diff changeset
5369 // been already stolen from us.
a61af66fc99e Initial load
duke
parents:
diff changeset
5370 // "He giveth and He taketh away."
a61af66fc99e Initial load
duke
parents:
diff changeset
5371 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
5372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5373 // Verify that we have no work before we resort to stealing
a61af66fc99e Initial load
duke
parents:
diff changeset
5374 assert(work_q->size() == 0, "Have work, shouldn't steal");
a61af66fc99e Initial load
duke
parents:
diff changeset
5375 // Try to steal from other queues that have work
a61af66fc99e Initial load
duke
parents:
diff changeset
5376 if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5377 NOT_PRODUCT(num_steals++;)
a61af66fc99e Initial load
duke
parents:
diff changeset
5378 assert(obj_to_scan->is_oop(), "Oops, not an oop!");
a61af66fc99e Initial load
duke
parents:
diff changeset
5379 assert(bm->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
a61af66fc99e Initial load
duke
parents:
diff changeset
5380 // Do scanning work
a61af66fc99e Initial load
duke
parents:
diff changeset
5381 obj_to_scan->oop_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5382 // Loop around, finish this work, and try to steal some more
a61af66fc99e Initial load
duke
parents:
diff changeset
5383 } else if (terminator()->offer_termination()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5384 break; // nirvana from the infinite cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
5385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5387 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
5388 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5389 gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
a61af66fc99e Initial load
duke
parents:
diff changeset
5390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5391 )
a61af66fc99e Initial load
duke
parents:
diff changeset
5392 assert(work_q->size() == 0 && _collector->overflow_list_is_empty(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5393 "Else our work is not yet done");
a61af66fc99e Initial load
duke
parents:
diff changeset
5394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5395
a61af66fc99e Initial load
duke
parents:
diff changeset
5396 // Return a thread-local PLAB recording array, as appropriate.
a61af66fc99e Initial load
duke
parents:
diff changeset
5397 void* CMSCollector::get_data_recorder(int thr_num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5398 if (_survivor_plab_array != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
5399 (CMSPLABRecordAlways ||
a61af66fc99e Initial load
duke
parents:
diff changeset
5400 (_collectorState > Marking && _collectorState < FinalMarking))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5401 assert(thr_num < (int)ParallelGCThreads, "thr_num is out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
5402 ChunkArray* ca = &_survivor_plab_array[thr_num];
a61af66fc99e Initial load
duke
parents:
diff changeset
5403 ca->reset(); // clear it so that fresh data is recorded
a61af66fc99e Initial load
duke
parents:
diff changeset
5404 return (void*) ca;
a61af66fc99e Initial load
duke
parents:
diff changeset
5405 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5406 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5409
a61af66fc99e Initial load
duke
parents:
diff changeset
5410 // Reset all the thread-local PLAB recording arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
5411 void CMSCollector::reset_survivor_plab_arrays() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5412 for (uint i = 0; i < ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5413 _survivor_plab_array[i].reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
5414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5416
a61af66fc99e Initial load
duke
parents:
diff changeset
5417 // Merge the per-thread plab arrays into the global survivor chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
5418 // array which will provide the partitioning of the survivor space
a61af66fc99e Initial load
duke
parents:
diff changeset
5419 // for CMS rescan.
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5420 void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv,
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5421 int no_of_gc_threads) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5422 assert(_survivor_plab_array != NULL, "Error");
a61af66fc99e Initial load
duke
parents:
diff changeset
5423 assert(_survivor_chunk_array != NULL, "Error");
a61af66fc99e Initial load
duke
parents:
diff changeset
5424 assert(_collectorState == FinalMarking, "Error");
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5425 for (int j = 0; j < no_of_gc_threads; j++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5426 _cursor[j] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5428 HeapWord* top = surv->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
5429 size_t i;
a61af66fc99e Initial load
duke
parents:
diff changeset
5430 for (i = 0; i < _survivor_chunk_capacity; i++) { // all sca entries
a61af66fc99e Initial load
duke
parents:
diff changeset
5431 HeapWord* min_val = top; // Higher than any PLAB address
a61af66fc99e Initial load
duke
parents:
diff changeset
5432 uint min_tid = 0; // position of min_val this round
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5433 for (int j = 0; j < no_of_gc_threads; j++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5434 ChunkArray* cur_sca = &_survivor_plab_array[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
5435 if (_cursor[j] == cur_sca->end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5436 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
5437 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5438 assert(_cursor[j] < cur_sca->end(), "ctl pt invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
5439 HeapWord* cur_val = cur_sca->nth(_cursor[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
5440 assert(surv->used_region().contains(cur_val), "Out of bounds value");
a61af66fc99e Initial load
duke
parents:
diff changeset
5441 if (cur_val < min_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5442 min_tid = j;
a61af66fc99e Initial load
duke
parents:
diff changeset
5443 min_val = cur_val;
a61af66fc99e Initial load
duke
parents:
diff changeset
5444 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5445 assert(cur_val < top, "All recorded addresses should be less");
a61af66fc99e Initial load
duke
parents:
diff changeset
5446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5448 // At this point min_val and min_tid are respectively
a61af66fc99e Initial load
duke
parents:
diff changeset
5449 // the least address in _survivor_plab_array[j]->nth(_cursor[j])
a61af66fc99e Initial load
duke
parents:
diff changeset
5450 // and the thread (j) that witnesses that address.
a61af66fc99e Initial load
duke
parents:
diff changeset
5451 // We record this address in the _survivor_chunk_array[i]
a61af66fc99e Initial load
duke
parents:
diff changeset
5452 // and increment _cursor[min_tid] prior to the next round i.
a61af66fc99e Initial load
duke
parents:
diff changeset
5453 if (min_val == top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5454 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
5455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5456 _survivor_chunk_array[i] = min_val;
a61af66fc99e Initial load
duke
parents:
diff changeset
5457 _cursor[min_tid]++;
a61af66fc99e Initial load
duke
parents:
diff changeset
5458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5459 // We are all done; record the size of the _survivor_chunk_array
a61af66fc99e Initial load
duke
parents:
diff changeset
5460 _survivor_chunk_index = i; // exclusive: [0, i)
a61af66fc99e Initial load
duke
parents:
diff changeset
5461 if (PrintCMSStatistics > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5462 gclog_or_tty->print(" (Survivor:" SIZE_FORMAT "chunks) ", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
5463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5464 // Verify that we used up all the recorded entries
a61af66fc99e Initial load
duke
parents:
diff changeset
5465 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
5466 size_t total = 0;
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5467 for (int j = 0; j < no_of_gc_threads; j++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5468 assert(_cursor[j] == _survivor_plab_array[j].end(), "Ctl pt invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
5469 total += _cursor[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
5470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5471 assert(total == _survivor_chunk_index, "Ctl Pt Invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
5472 // Check that the merged array is in sorted order
a61af66fc99e Initial load
duke
parents:
diff changeset
5473 if (total > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5474 for (size_t i = 0; i < total - 1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5475 if (PrintCMSStatistics > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5476 gclog_or_tty->print(" (chunk" SIZE_FORMAT ":" INTPTR_FORMAT ") ",
a61af66fc99e Initial load
duke
parents:
diff changeset
5477 i, _survivor_chunk_array[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
5478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5479 assert(_survivor_chunk_array[i] < _survivor_chunk_array[i+1],
a61af66fc99e Initial load
duke
parents:
diff changeset
5480 "Not sorted");
a61af66fc99e Initial load
duke
parents:
diff changeset
5481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5483 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
5484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5485
a61af66fc99e Initial load
duke
parents:
diff changeset
5486 // Set up the space's par_seq_tasks structure for work claiming
a61af66fc99e Initial load
duke
parents:
diff changeset
5487 // for parallel rescan of young gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
5488 // See ParRescanTask where this is currently used.
a61af66fc99e Initial load
duke
parents:
diff changeset
5489 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5490 CMSCollector::
a61af66fc99e Initial load
duke
parents:
diff changeset
5491 initialize_sequential_subtasks_for_young_gen_rescan(int n_threads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5492 assert(n_threads > 0, "Unexpected n_threads argument");
a61af66fc99e Initial load
duke
parents:
diff changeset
5493 DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
a61af66fc99e Initial load
duke
parents:
diff changeset
5494
a61af66fc99e Initial load
duke
parents:
diff changeset
5495 // Eden space
a61af66fc99e Initial load
duke
parents:
diff changeset
5496 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5497 SequentialSubTasksDone* pst = dng->eden()->par_seq_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
5498 assert(!pst->valid(), "Clobbering existing data?");
a61af66fc99e Initial load
duke
parents:
diff changeset
5499 // Each valid entry in [0, _eden_chunk_index) represents a task.
a61af66fc99e Initial load
duke
parents:
diff changeset
5500 size_t n_tasks = _eden_chunk_index + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5501 assert(n_tasks == 1 || _eden_chunk_array != NULL, "Error");
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5502 // Sets the condition for completion of the subtask (how many threads
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5503 // need to finish in order to be done).
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5504 pst->set_n_threads(n_threads);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5505 pst->set_n_tasks((int)n_tasks);
a61af66fc99e Initial load
duke
parents:
diff changeset
5506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5507
a61af66fc99e Initial load
duke
parents:
diff changeset
5508 // Merge the survivor plab arrays into _survivor_chunk_array
a61af66fc99e Initial load
duke
parents:
diff changeset
5509 if (_survivor_plab_array != NULL) {
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5510 merge_survivor_plab_arrays(dng->from(), n_threads);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5511 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5512 assert(_survivor_chunk_index == 0, "Error");
a61af66fc99e Initial load
duke
parents:
diff changeset
5513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5514
a61af66fc99e Initial load
duke
parents:
diff changeset
5515 // To space
a61af66fc99e Initial load
duke
parents:
diff changeset
5516 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5517 SequentialSubTasksDone* pst = dng->to()->par_seq_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
5518 assert(!pst->valid(), "Clobbering existing data?");
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5519 // Sets the condition for completion of the subtask (how many threads
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5520 // need to finish in order to be done).
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5521 pst->set_n_threads(n_threads);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5522 pst->set_n_tasks(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5523 assert(pst->valid(), "Error");
a61af66fc99e Initial load
duke
parents:
diff changeset
5524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5525
a61af66fc99e Initial load
duke
parents:
diff changeset
5526 // From space
a61af66fc99e Initial load
duke
parents:
diff changeset
5527 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5528 SequentialSubTasksDone* pst = dng->from()->par_seq_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
5529 assert(!pst->valid(), "Clobbering existing data?");
a61af66fc99e Initial load
duke
parents:
diff changeset
5530 size_t n_tasks = _survivor_chunk_index + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5531 assert(n_tasks == 1 || _survivor_chunk_array != NULL, "Error");
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5532 // Sets the condition for completion of the subtask (how many threads
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5533 // need to finish in order to be done).
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5534 pst->set_n_threads(n_threads);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5535 pst->set_n_tasks((int)n_tasks);
a61af66fc99e Initial load
duke
parents:
diff changeset
5536 assert(pst->valid(), "Error");
a61af66fc99e Initial load
duke
parents:
diff changeset
5537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5539
a61af66fc99e Initial load
duke
parents:
diff changeset
5540 // Parallel version of remark
a61af66fc99e Initial load
duke
parents:
diff changeset
5541 void CMSCollector::do_remark_parallel() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5542 GenCollectedHeap* gch = GenCollectedHeap::heap();
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5543 FlexibleWorkGang* workers = gch->workers();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5544 assert(workers != NULL, "Need parallel worker threads.");
a61af66fc99e Initial load
duke
parents:
diff changeset
5545 int n_workers = workers->total_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
5546 CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
5547 CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
5548
a61af66fc99e Initial load
duke
parents:
diff changeset
5549 CMSParRemarkTask tsk(this,
a61af66fc99e Initial load
duke
parents:
diff changeset
5550 cms_space, perm_space,
a61af66fc99e Initial load
duke
parents:
diff changeset
5551 n_workers, workers, task_queues());
a61af66fc99e Initial load
duke
parents:
diff changeset
5552
a61af66fc99e Initial load
duke
parents:
diff changeset
5553 // Set up for parallel process_strong_roots work.
a61af66fc99e Initial load
duke
parents:
diff changeset
5554 gch->set_par_threads(n_workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
5555 // We won't be iterating over the cards in the card table updating
a61af66fc99e Initial load
duke
parents:
diff changeset
5556 // the younger_gen cards, so we shouldn't call the following else
a61af66fc99e Initial load
duke
parents:
diff changeset
5557 // the verification code as well as subsequent younger_refs_iterate
a61af66fc99e Initial load
duke
parents:
diff changeset
5558 // code would get confused. XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
5559 // gch->rem_set()->prepare_for_younger_refs_iterate(true); // parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
5560
a61af66fc99e Initial load
duke
parents:
diff changeset
5561 // The young gen rescan work will not be done as part of
a61af66fc99e Initial load
duke
parents:
diff changeset
5562 // process_strong_roots (which currently doesn't knw how to
a61af66fc99e Initial load
duke
parents:
diff changeset
5563 // parallelize such a scan), but rather will be broken up into
a61af66fc99e Initial load
duke
parents:
diff changeset
5564 // a set of parallel tasks (via the sampling that the [abortable]
a61af66fc99e Initial load
duke
parents:
diff changeset
5565 // preclean phase did of EdenSpace, plus the [two] tasks of
a61af66fc99e Initial load
duke
parents:
diff changeset
5566 // scanning the [two] survivor spaces. Further fine-grain
a61af66fc99e Initial load
duke
parents:
diff changeset
5567 // parallelization of the scanning of the survivor spaces
a61af66fc99e Initial load
duke
parents:
diff changeset
5568 // themselves, and of precleaning of the younger gen itself
a61af66fc99e Initial load
duke
parents:
diff changeset
5569 // is deferred to the future.
a61af66fc99e Initial load
duke
parents:
diff changeset
5570 initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
5571
a61af66fc99e Initial load
duke
parents:
diff changeset
5572 // The dirty card rescan work is broken up into a "sequence"
a61af66fc99e Initial load
duke
parents:
diff changeset
5573 // of parallel tasks (per constituent space) that are dynamically
a61af66fc99e Initial load
duke
parents:
diff changeset
5574 // claimed by the parallel threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
5575 cms_space->initialize_sequential_subtasks_for_rescan(n_workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
5576 perm_space->initialize_sequential_subtasks_for_rescan(n_workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
5577
a61af66fc99e Initial load
duke
parents:
diff changeset
5578 // It turns out that even when we're using 1 thread, doing the work in a
a61af66fc99e Initial load
duke
parents:
diff changeset
5579 // separate thread causes wide variance in run times. We can't help this
a61af66fc99e Initial load
duke
parents:
diff changeset
5580 // in the multi-threaded case, but we special-case n=1 here to get
a61af66fc99e Initial load
duke
parents:
diff changeset
5581 // repeatable measurements of the 1-thread overhead of the parallel code.
a61af66fc99e Initial load
duke
parents:
diff changeset
5582 if (n_workers > 1) {
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5583 // Make refs discovery MT-safe, if it isn't already: it may not
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5584 // necessarily be so, since it's possible that we are doing
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5585 // ST marking.
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5586 ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), true);
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5587 GenCollectedHeap::StrongRootsScope srs(gch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5588 workers->run_task(&tsk);
a61af66fc99e Initial load
duke
parents:
diff changeset
5589 } else {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5590 GenCollectedHeap::StrongRootsScope srs(gch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5591 tsk.work(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5593 gch->set_par_threads(0); // 0 ==> non-parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
5594 // restore, single-threaded for now, any preserved marks
a61af66fc99e Initial load
duke
parents:
diff changeset
5595 // as a result of work_q overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
5596 restore_preserved_marks_if_any();
a61af66fc99e Initial load
duke
parents:
diff changeset
5597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5598
a61af66fc99e Initial load
duke
parents:
diff changeset
5599 // Non-parallel version of remark
a61af66fc99e Initial load
duke
parents:
diff changeset
5600 void CMSCollector::do_remark_non_parallel() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5601 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
5602 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
5603 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
5604 MarkRefsIntoAndScanClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
5605 mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
a61af66fc99e Initial load
duke
parents:
diff changeset
5606 &_markStack, &_revisitStack, this,
a61af66fc99e Initial load
duke
parents:
diff changeset
5607 false /* should_yield */, false /* not precleaning */);
a61af66fc99e Initial load
duke
parents:
diff changeset
5608 MarkFromDirtyCardsClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
5609 markFromDirtyCardsClosure(this, _span,
a61af66fc99e Initial load
duke
parents:
diff changeset
5610 NULL, // space is set further below
a61af66fc99e Initial load
duke
parents:
diff changeset
5611 &_markBitMap, &_markStack, &_revisitStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
5612 &mrias_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
5613 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5614 TraceTime t("grey object rescan", PrintGCDetails, false, gclog_or_tty);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
5615 // Iterate over the dirty cards, setting the corresponding bits in the
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
5616 // mod union table.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5617 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5618 ModUnionClosure modUnionClosure(&_modUnionTable);
a61af66fc99e Initial load
duke
parents:
diff changeset
5619 _ct->ct_bs()->dirty_card_iterate(
a61af66fc99e Initial load
duke
parents:
diff changeset
5620 _cmsGen->used_region(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5621 &modUnionClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
5622 _ct->ct_bs()->dirty_card_iterate(
a61af66fc99e Initial load
duke
parents:
diff changeset
5623 _permGen->used_region(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5624 &modUnionClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
5625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5626 // Having transferred these marks into the modUnionTable, we just need
a61af66fc99e Initial load
duke
parents:
diff changeset
5627 // to rescan the marked objects on the dirty cards in the modUnionTable.
a61af66fc99e Initial load
duke
parents:
diff changeset
5628 // The initial marking may have been done during an asynchronous
a61af66fc99e Initial load
duke
parents:
diff changeset
5629 // collection so there may be dirty bits in the mod-union table.
a61af66fc99e Initial load
duke
parents:
diff changeset
5630 const int alignment =
a61af66fc99e Initial load
duke
parents:
diff changeset
5631 CardTableModRefBS::card_size * BitsPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
5632 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5633 // ... First handle dirty cards in CMS gen
a61af66fc99e Initial load
duke
parents:
diff changeset
5634 markFromDirtyCardsClosure.set_space(_cmsGen->cmsSpace());
a61af66fc99e Initial load
duke
parents:
diff changeset
5635 MemRegion ur = _cmsGen->used_region();
a61af66fc99e Initial load
duke
parents:
diff changeset
5636 HeapWord* lb = ur.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
5637 HeapWord* ub = (HeapWord*)round_to((intptr_t)ur.end(), alignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
5638 MemRegion cms_span(lb, ub);
a61af66fc99e Initial load
duke
parents:
diff changeset
5639 _modUnionTable.dirty_range_iterate_clear(cms_span,
a61af66fc99e Initial load
duke
parents:
diff changeset
5640 &markFromDirtyCardsClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
5641 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
5642 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5643 gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in cms gen) ",
a61af66fc99e Initial load
duke
parents:
diff changeset
5644 markFromDirtyCardsClosure.num_dirty_cards());
a61af66fc99e Initial load
duke
parents:
diff changeset
5645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5647 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5648 // .. and then repeat for dirty cards in perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
5649 markFromDirtyCardsClosure.set_space(_permGen->cmsSpace());
a61af66fc99e Initial load
duke
parents:
diff changeset
5650 MemRegion ur = _permGen->used_region();
a61af66fc99e Initial load
duke
parents:
diff changeset
5651 HeapWord* lb = ur.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
5652 HeapWord* ub = (HeapWord*)round_to((intptr_t)ur.end(), alignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
5653 MemRegion perm_span(lb, ub);
a61af66fc99e Initial load
duke
parents:
diff changeset
5654 _modUnionTable.dirty_range_iterate_clear(perm_span,
a61af66fc99e Initial load
duke
parents:
diff changeset
5655 &markFromDirtyCardsClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
5656 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
5657 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5658 gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in perm gen) ",
a61af66fc99e Initial load
duke
parents:
diff changeset
5659 markFromDirtyCardsClosure.num_dirty_cards());
a61af66fc99e Initial load
duke
parents:
diff changeset
5660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5663 if (VerifyDuringGC &&
a61af66fc99e Initial load
duke
parents:
diff changeset
5664 GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5665 HandleMark hm; // Discard invalid handles created during verification
a61af66fc99e Initial load
duke
parents:
diff changeset
5666 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
5667 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5668 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5669 TraceTime t("root rescan", PrintGCDetails, false, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
5670
a61af66fc99e Initial load
duke
parents:
diff changeset
5671 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
5672
a61af66fc99e Initial load
duke
parents:
diff changeset
5673 gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5674 GenCollectedHeap::StrongRootsScope srs(gch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5675 gch->gen_process_strong_roots(_cmsGen->level(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5676 true, // younger gens as roots
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5677 false, // use the local StrongRootsScope
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5678 true, // collecting perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
5679 SharedHeap::ScanningOption(roots_scanning_options()),
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5680 &mrias_cl,
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5681 true, // walk code active on stacks
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5682 NULL);
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5683 assert(should_unload_classes()
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5684 || (roots_scanning_options() & SharedHeap::SO_CodeCache),
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 798
diff changeset
5685 "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5687 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
5688 // Restore evacuated mark words, if any, used for overflow list links
a61af66fc99e Initial load
duke
parents:
diff changeset
5689 if (!CMSOverflowEarlyRestoration) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5690 restore_preserved_marks_if_any();
a61af66fc99e Initial load
duke
parents:
diff changeset
5691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5692 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
5693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5694
a61af66fc99e Initial load
duke
parents:
diff changeset
5695 ////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
5696 // Parallel Reference Processing Task Proxy Class
a61af66fc99e Initial load
duke
parents:
diff changeset
5697 ////////////////////////////////////////////////////////
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5698 class CMSRefProcTaskProxy: public AbstractGangTaskWOopQueues {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5699 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
5700 CMSCollector* _collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
5701 CMSBitMap* _mark_bit_map;
143
b5489bb705c9 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 113
diff changeset
5702 const MemRegion _span;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5703 ProcessTask& _task;
a61af66fc99e Initial load
duke
parents:
diff changeset
5704
a61af66fc99e Initial load
duke
parents:
diff changeset
5705 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
5706 CMSRefProcTaskProxy(ProcessTask& task,
a61af66fc99e Initial load
duke
parents:
diff changeset
5707 CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
5708 const MemRegion& span,
a61af66fc99e Initial load
duke
parents:
diff changeset
5709 CMSBitMap* mark_bit_map,
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5710 AbstractWorkGang* workers,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5711 OopTaskQueueSet* task_queues):
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5712 // XXX Should superclass AGTWOQ also know about AWG since it knows
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5713 // about the task_queues used by the AWG? Then it could initialize
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5714 // the terminator() object. See 6984287. The set_for_termination()
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5715 // below is a temporary band-aid for the regression in 6984287.
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5716 AbstractGangTaskWOopQueues("Process referents by policy in parallel",
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5717 task_queues),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5718 _task(task),
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5719 _collector(collector), _span(span), _mark_bit_map(mark_bit_map)
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5720 {
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5721 assert(_collector->_span.equals(_span) && !_span.is_empty(),
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5722 "Inconsistency in _span");
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5723 set_for_termination(workers->active_workers());
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5724 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5725
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5726 OopTaskQueueSet* task_queues() { return queues(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5727
a61af66fc99e Initial load
duke
parents:
diff changeset
5728 OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
a61af66fc99e Initial load
duke
parents:
diff changeset
5729
a61af66fc99e Initial load
duke
parents:
diff changeset
5730 void do_work_steal(int i,
a61af66fc99e Initial load
duke
parents:
diff changeset
5731 CMSParDrainMarkingStackClosure* drain,
a61af66fc99e Initial load
duke
parents:
diff changeset
5732 CMSParKeepAliveClosure* keep_alive,
a61af66fc99e Initial load
duke
parents:
diff changeset
5733 int* seed);
a61af66fc99e Initial load
duke
parents:
diff changeset
5734
a61af66fc99e Initial load
duke
parents:
diff changeset
5735 virtual void work(int i);
a61af66fc99e Initial load
duke
parents:
diff changeset
5736 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5737
a61af66fc99e Initial load
duke
parents:
diff changeset
5738 void CMSRefProcTaskProxy::work(int i) {
143
b5489bb705c9 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 113
diff changeset
5739 assert(_collector->_span.equals(_span), "Inconsistency in _span");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5740 CMSParKeepAliveClosure par_keep_alive(_collector, _span,
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5741 _mark_bit_map,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5742 &_collector->_revisitStack,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5743 work_queue(i));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5744 CMSParDrainMarkingStackClosure par_drain_stack(_collector, _span,
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5745 _mark_bit_map,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5746 &_collector->_revisitStack,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5747 work_queue(i));
143
b5489bb705c9 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 113
diff changeset
5748 CMSIsAliveClosure is_alive_closure(_span, _mark_bit_map);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5749 _task.work(i, is_alive_closure, par_keep_alive, par_drain_stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
5750 if (_task.marks_oops_alive()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5751 do_work_steal(i, &par_drain_stack, &par_keep_alive,
a61af66fc99e Initial load
duke
parents:
diff changeset
5752 _collector->hash_seed(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
5753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5754 assert(work_queue(i)->size() == 0, "work_queue should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
5755 assert(_collector->_overflow_list == NULL, "non-empty _overflow_list");
a61af66fc99e Initial load
duke
parents:
diff changeset
5756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5757
a61af66fc99e Initial load
duke
parents:
diff changeset
5758 class CMSRefEnqueueTaskProxy: public AbstractGangTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
5759 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
5760 EnqueueTask& _task;
a61af66fc99e Initial load
duke
parents:
diff changeset
5761
a61af66fc99e Initial load
duke
parents:
diff changeset
5762 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
5763 CMSRefEnqueueTaskProxy(EnqueueTask& task)
a61af66fc99e Initial load
duke
parents:
diff changeset
5764 : AbstractGangTask("Enqueue reference objects in parallel"),
a61af66fc99e Initial load
duke
parents:
diff changeset
5765 _task(task)
a61af66fc99e Initial load
duke
parents:
diff changeset
5766 { }
a61af66fc99e Initial load
duke
parents:
diff changeset
5767
a61af66fc99e Initial load
duke
parents:
diff changeset
5768 virtual void work(int i)
a61af66fc99e Initial load
duke
parents:
diff changeset
5769 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5770 _task.work(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
5771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5772 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5773
a61af66fc99e Initial load
duke
parents:
diff changeset
5774 CMSParKeepAliveClosure::CMSParKeepAliveClosure(CMSCollector* collector,
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5775 MemRegion span, CMSBitMap* bit_map, CMSMarkStack* revisit_stack,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5776 OopTaskQueue* work_queue):
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5777 Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5778 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
5779 _bit_map(bit_map),
a61af66fc99e Initial load
duke
parents:
diff changeset
5780 _work_queue(work_queue),
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5781 _mark_and_push(collector, span, bit_map, revisit_stack, work_queue),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5782 _low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
a61af66fc99e Initial load
duke
parents:
diff changeset
5783 (uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads)))
a61af66fc99e Initial load
duke
parents:
diff changeset
5784 { }
a61af66fc99e Initial load
duke
parents:
diff changeset
5785
a61af66fc99e Initial load
duke
parents:
diff changeset
5786 // . see if we can share work_queues with ParNew? XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
5787 void CMSRefProcTaskProxy::do_work_steal(int i,
a61af66fc99e Initial load
duke
parents:
diff changeset
5788 CMSParDrainMarkingStackClosure* drain,
a61af66fc99e Initial load
duke
parents:
diff changeset
5789 CMSParKeepAliveClosure* keep_alive,
a61af66fc99e Initial load
duke
parents:
diff changeset
5790 int* seed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5791 OopTaskQueue* work_q = work_queue(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
5792 NOT_PRODUCT(int num_steals = 0;)
a61af66fc99e Initial load
duke
parents:
diff changeset
5793 oop obj_to_scan;
a61af66fc99e Initial load
duke
parents:
diff changeset
5794
a61af66fc99e Initial load
duke
parents:
diff changeset
5795 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5796 // Completely finish any left over work from (an) earlier round(s)
a61af66fc99e Initial load
duke
parents:
diff changeset
5797 drain->trim_queue(0);
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 628
diff changeset
5798 size_t num_from_overflow_list = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 628
diff changeset
5799 (size_t)ParGCDesiredObjsFromOverflowList);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5800 // Now check if there's any work in the overflow list
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5801 // Passing ParallelGCThreads as the third parameter, no_of_gc_threads,
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5802 // only affects the number of attempts made to get work from the
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5803 // overflow list and does not affect the number of workers. Just
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5804 // pass ParallelGCThreads so this behavior is unchanged.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5805 if (_collector->par_take_from_overflow_list(num_from_overflow_list,
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5806 work_q,
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5807 ParallelGCThreads)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5808 // Found something in global overflow list;
a61af66fc99e Initial load
duke
parents:
diff changeset
5809 // not yet ready to go stealing work from others.
a61af66fc99e Initial load
duke
parents:
diff changeset
5810 // We'd like to assert(work_q->size() != 0, ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
5811 // because we just took work from the overflow list,
a61af66fc99e Initial load
duke
parents:
diff changeset
5812 // but of course we can't, since all of that might have
a61af66fc99e Initial load
duke
parents:
diff changeset
5813 // been already stolen from us.
a61af66fc99e Initial load
duke
parents:
diff changeset
5814 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
5815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5816 // Verify that we have no work before we resort to stealing
a61af66fc99e Initial load
duke
parents:
diff changeset
5817 assert(work_q->size() == 0, "Have work, shouldn't steal");
a61af66fc99e Initial load
duke
parents:
diff changeset
5818 // Try to steal from other queues that have work
a61af66fc99e Initial load
duke
parents:
diff changeset
5819 if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5820 NOT_PRODUCT(num_steals++;)
a61af66fc99e Initial load
duke
parents:
diff changeset
5821 assert(obj_to_scan->is_oop(), "Oops, not an oop!");
a61af66fc99e Initial load
duke
parents:
diff changeset
5822 assert(_mark_bit_map->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
a61af66fc99e Initial load
duke
parents:
diff changeset
5823 // Do scanning work
a61af66fc99e Initial load
duke
parents:
diff changeset
5824 obj_to_scan->oop_iterate(keep_alive);
a61af66fc99e Initial load
duke
parents:
diff changeset
5825 // Loop around, finish this work, and try to steal some more
a61af66fc99e Initial load
duke
parents:
diff changeset
5826 } else if (terminator()->offer_termination()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5827 break; // nirvana from the infinite cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
5828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5830 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
5831 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5832 gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
a61af66fc99e Initial load
duke
parents:
diff changeset
5833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5834 )
a61af66fc99e Initial load
duke
parents:
diff changeset
5835 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5836
a61af66fc99e Initial load
duke
parents:
diff changeset
5837 void CMSRefProcTaskExecutor::execute(ProcessTask& task)
a61af66fc99e Initial load
duke
parents:
diff changeset
5838 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5839 GenCollectedHeap* gch = GenCollectedHeap::heap();
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5840 FlexibleWorkGang* workers = gch->workers();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5841 assert(workers != NULL, "Need parallel worker threads.");
a61af66fc99e Initial load
duke
parents:
diff changeset
5842 CMSRefProcTaskProxy rp_task(task, &_collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
5843 _collector.ref_processor()->span(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5844 _collector.markBitMap(),
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5845 workers, _collector.task_queues());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5846 workers->run_task(&rp_task);
a61af66fc99e Initial load
duke
parents:
diff changeset
5847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5848
a61af66fc99e Initial load
duke
parents:
diff changeset
5849 void CMSRefProcTaskExecutor::execute(EnqueueTask& task)
a61af66fc99e Initial load
duke
parents:
diff changeset
5850 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5851
a61af66fc99e Initial load
duke
parents:
diff changeset
5852 GenCollectedHeap* gch = GenCollectedHeap::heap();
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5853 FlexibleWorkGang* workers = gch->workers();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5854 assert(workers != NULL, "Need parallel worker threads.");
a61af66fc99e Initial load
duke
parents:
diff changeset
5855 CMSRefEnqueueTaskProxy enq_task(task);
a61af66fc99e Initial load
duke
parents:
diff changeset
5856 workers->run_task(&enq_task);
a61af66fc99e Initial load
duke
parents:
diff changeset
5857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5858
a61af66fc99e Initial load
duke
parents:
diff changeset
5859 void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5860
a61af66fc99e Initial load
duke
parents:
diff changeset
5861 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
5862 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
5863
a61af66fc99e Initial load
duke
parents:
diff changeset
5864 ReferenceProcessor* rp = ref_processor();
a61af66fc99e Initial load
duke
parents:
diff changeset
5865 assert(rp->span().equals(_span), "Spans should be equal");
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
5866 assert(!rp->enqueuing_is_done(), "Enqueuing should not be complete");
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
5867 // Process weak references.
457
27a80744a83b 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 453
diff changeset
5868 rp->setup_policy(clear_all_soft_refs);
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
5869 verify_work_stacks_empty();
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
5870
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5871 CMSKeepAliveClosure cmsKeepAliveClosure(this, _span, &_markBitMap,
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5872 &_markStack, &_revisitStack,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
5873 false /* !preclean */);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5874 CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this,
a61af66fc99e Initial load
duke
parents:
diff changeset
5875 _span, &_markBitMap, &_markStack,
452
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
5876 &cmsKeepAliveClosure, false /* !preclean */);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5877 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5878 TraceTime t("weak refs processing", PrintGCDetails, false, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
5879 if (rp->processing_is_mt()) {
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5880 // Set the degree of MT here. If the discovery is done MT, there
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5881 // may have been a different number of threads doing the discovery
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5882 // and a different number of discovered lists may have Ref objects.
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5883 // That is OK as long as the Reference lists are balanced (see
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5884 // balance_all_queues() and balance_queues()).
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5885
2369
92da084fefc9 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 2365
diff changeset
5886 rp->set_active_mt_degree(ParallelGCThreads);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5887 CMSRefProcTaskExecutor task_executor(*this);
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
5888 rp->process_discovered_references(&_is_alive_closure,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5889 &cmsKeepAliveClosure,
a61af66fc99e Initial load
duke
parents:
diff changeset
5890 &cmsDrainMarkingStackClosure,
a61af66fc99e Initial load
duke
parents:
diff changeset
5891 &task_executor);
a61af66fc99e Initial load
duke
parents:
diff changeset
5892 } else {
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
5893 rp->process_discovered_references(&_is_alive_closure,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5894 &cmsKeepAliveClosure,
a61af66fc99e Initial load
duke
parents:
diff changeset
5895 &cmsDrainMarkingStackClosure,
a61af66fc99e Initial load
duke
parents:
diff changeset
5896 NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5898 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
5899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5900
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
5901 if (should_unload_classes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5902 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5903 TraceTime t("class unloading", PrintGCDetails, false, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
5904
a61af66fc99e Initial load
duke
parents:
diff changeset
5905 // Follow SystemDictionary roots and unload classes
a61af66fc99e Initial load
duke
parents:
diff changeset
5906 bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
5907
a61af66fc99e Initial load
duke
parents:
diff changeset
5908 // Follow CodeCache roots and unload any methods marked for unloading
a61af66fc99e Initial load
duke
parents:
diff changeset
5909 CodeCache::do_unloading(&_is_alive_closure,
a61af66fc99e Initial load
duke
parents:
diff changeset
5910 &cmsKeepAliveClosure,
a61af66fc99e Initial load
duke
parents:
diff changeset
5911 purged_class);
a61af66fc99e Initial load
duke
parents:
diff changeset
5912
a61af66fc99e Initial load
duke
parents:
diff changeset
5913 cmsDrainMarkingStackClosure.do_void();
a61af66fc99e Initial load
duke
parents:
diff changeset
5914 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
5915
a61af66fc99e Initial load
duke
parents:
diff changeset
5916 // Update subklass/sibling/implementor links in KlassKlass descendants
a61af66fc99e Initial load
duke
parents:
diff changeset
5917 assert(!_revisitStack.isEmpty(), "revisit stack should not be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
5918 oop k;
a61af66fc99e Initial load
duke
parents:
diff changeset
5919 while ((k = _revisitStack.pop()) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5920 ((Klass*)(oopDesc*)k)->follow_weak_klass_links(
a61af66fc99e Initial load
duke
parents:
diff changeset
5921 &_is_alive_closure,
a61af66fc99e Initial load
duke
parents:
diff changeset
5922 &cmsKeepAliveClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
5923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5924 assert(!ClassUnloading ||
a61af66fc99e Initial load
duke
parents:
diff changeset
5925 (_markStack.isEmpty() && overflow_list_is_empty()),
a61af66fc99e Initial load
duke
parents:
diff changeset
5926 "Should not have found new reachable objects");
a61af66fc99e Initial load
duke
parents:
diff changeset
5927 assert(_revisitStack.isEmpty(), "revisit stack should have been drained");
a61af66fc99e Initial load
duke
parents:
diff changeset
5928 cmsDrainMarkingStackClosure.do_void();
a61af66fc99e Initial load
duke
parents:
diff changeset
5929 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
5930 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5931
a61af66fc99e Initial load
duke
parents:
diff changeset
5932 {
2379
b099aaf51bf8 6962931: move interned strings out of the perm gen
jcoomes
parents: 2369
diff changeset
5933 TraceTime t("scrub symbol table", PrintGCDetails, false, gclog_or_tty);
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2147
diff changeset
5934 // Clean up unreferenced symbols in symbol table.
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2147
diff changeset
5935 SymbolTable::unlink();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5938
2379
b099aaf51bf8 6962931: move interned strings out of the perm gen
jcoomes
parents: 2369
diff changeset
5939 if (should_unload_classes() || !JavaObjectsInPerm) {
b099aaf51bf8 6962931: move interned strings out of the perm gen
jcoomes
parents: 2369
diff changeset
5940 TraceTime t("scrub string table", PrintGCDetails, false, gclog_or_tty);
b099aaf51bf8 6962931: move interned strings out of the perm gen
jcoomes
parents: 2369
diff changeset
5941 // Now clean up stale oops in StringTable
b099aaf51bf8 6962931: move interned strings out of the perm gen
jcoomes
parents: 2369
diff changeset
5942 StringTable::unlink(&_is_alive_closure);
b099aaf51bf8 6962931: move interned strings out of the perm gen
jcoomes
parents: 2369
diff changeset
5943 }
b099aaf51bf8 6962931: move interned strings out of the perm gen
jcoomes
parents: 2369
diff changeset
5944
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5945 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
5946 // Restore any preserved marks as a result of mark stack or
a61af66fc99e Initial load
duke
parents:
diff changeset
5947 // work queue overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
5948 restore_preserved_marks_if_any(); // done single-threaded for now
a61af66fc99e Initial load
duke
parents:
diff changeset
5949
a61af66fc99e Initial load
duke
parents:
diff changeset
5950 rp->set_enqueuing_is_done(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
5951 if (rp->processing_is_mt()) {
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
5952 rp->balance_all_queues();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5953 CMSRefProcTaskExecutor task_executor(*this);
a61af66fc99e Initial load
duke
parents:
diff changeset
5954 rp->enqueue_discovered_references(&task_executor);
a61af66fc99e Initial load
duke
parents:
diff changeset
5955 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5956 rp->enqueue_discovered_references(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5958 rp->verify_no_references_recorded();
a61af66fc99e Initial load
duke
parents:
diff changeset
5959 assert(!rp->discovery_enabled(), "should have been disabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
5960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5961
a61af66fc99e Initial load
duke
parents:
diff changeset
5962 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
5963 void CMSCollector::check_correct_thread_executing() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5964 Thread* t = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
5965 // Only the VM thread or the CMS thread should be here.
a61af66fc99e Initial load
duke
parents:
diff changeset
5966 assert(t->is_ConcurrentGC_thread() || t->is_VM_thread(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5967 "Unexpected thread type");
a61af66fc99e Initial load
duke
parents:
diff changeset
5968 // If this is the vm thread, the foreground process
a61af66fc99e Initial load
duke
parents:
diff changeset
5969 // should not be waiting. Note that _foregroundGCIsActive is
a61af66fc99e Initial load
duke
parents:
diff changeset
5970 // true while the foreground collector is waiting.
a61af66fc99e Initial load
duke
parents:
diff changeset
5971 if (_foregroundGCShouldWait) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5972 // We cannot be the VM thread
a61af66fc99e Initial load
duke
parents:
diff changeset
5973 assert(t->is_ConcurrentGC_thread(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5974 "Should be CMS thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
5975 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5976 // We can be the CMS thread only if we are in a stop-world
a61af66fc99e Initial load
duke
parents:
diff changeset
5977 // phase of CMS collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
5978 if (t->is_ConcurrentGC_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5979 assert(_collectorState == InitialMarking ||
a61af66fc99e Initial load
duke
parents:
diff changeset
5980 _collectorState == FinalMarking,
a61af66fc99e Initial load
duke
parents:
diff changeset
5981 "Should be a stop-world phase");
a61af66fc99e Initial load
duke
parents:
diff changeset
5982 // The CMS thread should be holding the CMS_token.
a61af66fc99e Initial load
duke
parents:
diff changeset
5983 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5984 "Potential interference with concurrently "
a61af66fc99e Initial load
duke
parents:
diff changeset
5985 "executing VM thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
5986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5988 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5989 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5990
a61af66fc99e Initial load
duke
parents:
diff changeset
5991 void CMSCollector::sweep(bool asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5992 assert(_collectorState == Sweeping, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
5993 check_correct_thread_executing();
a61af66fc99e Initial load
duke
parents:
diff changeset
5994 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
5995 verify_overflow_empty();
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
5996 increment_sweep_count();
1703
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
5997 TraceCMSMemoryManagerStats tms(_collectorState);
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
5998
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
5999 _inter_sweep_timer.stop();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6000 _inter_sweep_estimate.sample(_inter_sweep_timer.seconds());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6001 size_policy()->avg_cms_free_at_sweep()->sample(_cmsGen->free());
a61af66fc99e Initial load
duke
parents:
diff changeset
6002
a61af66fc99e Initial load
duke
parents:
diff changeset
6003 // PermGen verification support: If perm gen sweeping is disabled in
a61af66fc99e Initial load
duke
parents:
diff changeset
6004 // this cycle, we preserve the perm gen object "deadness" information
a61af66fc99e Initial load
duke
parents:
diff changeset
6005 // in the perm_gen_verify_bit_map. In order to do that we traverse
a61af66fc99e Initial load
duke
parents:
diff changeset
6006 // all blocks in perm gen and mark all dead objects.
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
6007 if (verifying() && !should_unload_classes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6008 assert(perm_gen_verify_bit_map()->sizeInBits() != 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
6009 "Should have already been allocated");
a61af66fc99e Initial load
duke
parents:
diff changeset
6010 MarkDeadObjectsClosure mdo(this, _permGen->cmsSpace(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6011 markBitMap(), perm_gen_verify_bit_map());
7
2faf283ce688 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 0
diff changeset
6012 if (asynch) {
2faf283ce688 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 0
diff changeset
6013 CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
2faf283ce688 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 0
diff changeset
6014 bitMapLock());
2faf283ce688 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 0
diff changeset
6015 _permGen->cmsSpace()->blk_iterate(&mdo);
2faf283ce688 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 0
diff changeset
6016 } else {
2faf283ce688 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 0
diff changeset
6017 // In the case of synchronous sweep, we already have
2faf283ce688 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 0
diff changeset
6018 // the requisite locks/tokens.
2faf283ce688 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 0
diff changeset
6019 _permGen->cmsSpace()->blk_iterate(&mdo);
2faf283ce688 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 0
diff changeset
6020 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6021 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6022
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6023 assert(!_intra_sweep_timer.is_active(), "Should not be active");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6024 _intra_sweep_timer.reset();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6025 _intra_sweep_timer.start();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6026 if (asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6027 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
6028 CMSPhaseAccounting pa(this, "sweep", !PrintGCDetails);
a61af66fc99e Initial load
duke
parents:
diff changeset
6029 // First sweep the old gen then the perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
6030 {
a61af66fc99e Initial load
duke
parents:
diff changeset
6031 CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6032 bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
6033 sweepWork(_cmsGen, asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
6034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6035
a61af66fc99e Initial load
duke
parents:
diff changeset
6036 // Now repeat for perm gen
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
6037 if (should_unload_classes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6038 CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6039 bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
6040 sweepWork(_permGen, asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
6041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6042
a61af66fc99e Initial load
duke
parents:
diff changeset
6043 // Update Universe::_heap_*_at_gc figures.
a61af66fc99e Initial load
duke
parents:
diff changeset
6044 // We need all the free list locks to make the abstract state
a61af66fc99e Initial load
duke
parents:
diff changeset
6045 // transition from Sweeping to Resetting. See detailed note
a61af66fc99e Initial load
duke
parents:
diff changeset
6046 // further below.
a61af66fc99e Initial load
duke
parents:
diff changeset
6047 {
a61af66fc99e Initial load
duke
parents:
diff changeset
6048 CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6049 _permGen->freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
6050 // Update heap occupancy information which is used as
a61af66fc99e Initial load
duke
parents:
diff changeset
6051 // input to soft ref clearing policy at the next gc.
a61af66fc99e Initial load
duke
parents:
diff changeset
6052 Universe::update_heap_info_at_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
6053 _collectorState = Resizing;
a61af66fc99e Initial load
duke
parents:
diff changeset
6054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6055 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6056 // already have needed locks
a61af66fc99e Initial load
duke
parents:
diff changeset
6057 sweepWork(_cmsGen, asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
6058
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
6059 if (should_unload_classes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6060 sweepWork(_permGen, asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
6061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6062 // Update heap occupancy information which is used as
a61af66fc99e Initial load
duke
parents:
diff changeset
6063 // input to soft ref clearing policy at the next gc.
a61af66fc99e Initial load
duke
parents:
diff changeset
6064 Universe::update_heap_info_at_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
6065 _collectorState = Resizing;
a61af66fc99e Initial load
duke
parents:
diff changeset
6066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6067 verify_work_stacks_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
6068 verify_overflow_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
6069
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6070 _intra_sweep_timer.stop();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6071 _intra_sweep_estimate.sample(_intra_sweep_timer.seconds());
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6072
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6073 _inter_sweep_timer.reset();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6074 _inter_sweep_timer.start();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6075
a61af66fc99e Initial load
duke
parents:
diff changeset
6076 update_time_of_last_gc(os::javaTimeMillis());
a61af66fc99e Initial load
duke
parents:
diff changeset
6077
a61af66fc99e Initial load
duke
parents:
diff changeset
6078 // NOTE on abstract state transitions:
a61af66fc99e Initial load
duke
parents:
diff changeset
6079 // Mutators allocate-live and/or mark the mod-union table dirty
a61af66fc99e Initial load
duke
parents:
diff changeset
6080 // based on the state of the collection. The former is done in
a61af66fc99e Initial load
duke
parents:
diff changeset
6081 // the interval [Marking, Sweeping] and the latter in the interval
a61af66fc99e Initial load
duke
parents:
diff changeset
6082 // [Marking, Sweeping). Thus the transitions into the Marking state
a61af66fc99e Initial load
duke
parents:
diff changeset
6083 // and out of the Sweeping state must be synchronously visible
a61af66fc99e Initial load
duke
parents:
diff changeset
6084 // globally to the mutators.
a61af66fc99e Initial load
duke
parents:
diff changeset
6085 // The transition into the Marking state happens with the world
a61af66fc99e Initial load
duke
parents:
diff changeset
6086 // stopped so the mutators will globally see it. Sweeping is
a61af66fc99e Initial load
duke
parents:
diff changeset
6087 // done asynchronously by the background collector so the transition
a61af66fc99e Initial load
duke
parents:
diff changeset
6088 // from the Sweeping state to the Resizing state must be done
a61af66fc99e Initial load
duke
parents:
diff changeset
6089 // under the freelistLock (as is the check for whether to
a61af66fc99e Initial load
duke
parents:
diff changeset
6090 // allocate-live and whether to dirty the mod-union table).
a61af66fc99e Initial load
duke
parents:
diff changeset
6091 assert(_collectorState == Resizing, "Change of collector state to"
a61af66fc99e Initial load
duke
parents:
diff changeset
6092 " Resizing must be done under the freelistLocks (plural)");
a61af66fc99e Initial load
duke
parents:
diff changeset
6093
1888
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
6094 // Now that sweeping has been completed, we clear
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
6095 // the incremental_collection_failed flag,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6096 // thus inviting a younger gen collection to promote into
a61af66fc99e Initial load
duke
parents:
diff changeset
6097 // this generation. If such a promotion may still fail,
a61af66fc99e Initial load
duke
parents:
diff changeset
6098 // the flag will be set again when a young collection is
a61af66fc99e Initial load
duke
parents:
diff changeset
6099 // attempted.
a61af66fc99e Initial load
duke
parents:
diff changeset
6100 GenCollectedHeap* gch = GenCollectedHeap::heap();
1888
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1837
diff changeset
6101 gch->clear_incremental_collection_failed(); // Worth retrying as fresh space may have been freed up
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6102 gch->update_full_collections_completed(_collection_count_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
6103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6104
a61af66fc99e Initial load
duke
parents:
diff changeset
6105 // FIX ME!!! Looks like this belongs in CFLSpace, with
a61af66fc99e Initial load
duke
parents:
diff changeset
6106 // CMSGen merely delegating to it.
a61af66fc99e Initial load
duke
parents:
diff changeset
6107 void ConcurrentMarkSweepGeneration::setNearLargestChunk() {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6108 double nearLargestPercent = FLSLargestBlockCoalesceProximity;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6109 HeapWord* minAddr = _cmsSpace->bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
6110 HeapWord* largestAddr =
a61af66fc99e Initial load
duke
parents:
diff changeset
6111 (HeapWord*) _cmsSpace->dictionary()->findLargestDict();
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6112 if (largestAddr == NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6113 // The dictionary appears to be empty. In this case
a61af66fc99e Initial load
duke
parents:
diff changeset
6114 // try to coalesce at the end of the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
6115 largestAddr = _cmsSpace->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
6116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6117 size_t largestOffset = pointer_delta(largestAddr, minAddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
6118 size_t nearLargestOffset =
a61af66fc99e Initial load
duke
parents:
diff changeset
6119 (size_t)((double)largestOffset * nearLargestPercent) - MinChunkSize;
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6120 if (PrintFLSStatistics != 0) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6121 gclog_or_tty->print_cr(
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6122 "CMS: Large Block: " PTR_FORMAT ";"
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6123 " Proximity: " PTR_FORMAT " -> " PTR_FORMAT,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6124 largestAddr,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6125 _cmsSpace->nearLargestChunk(), minAddr + nearLargestOffset);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6126 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6127 _cmsSpace->set_nearLargestChunk(minAddr + nearLargestOffset);
a61af66fc99e Initial load
duke
parents:
diff changeset
6128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6129
a61af66fc99e Initial load
duke
parents:
diff changeset
6130 bool ConcurrentMarkSweepGeneration::isNearLargestChunk(HeapWord* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6131 return addr >= _cmsSpace->nearLargestChunk();
a61af66fc99e Initial load
duke
parents:
diff changeset
6132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6133
a61af66fc99e Initial load
duke
parents:
diff changeset
6134 FreeChunk* ConcurrentMarkSweepGeneration::find_chunk_at_end() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6135 return _cmsSpace->find_chunk_at_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
6136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6137
a61af66fc99e Initial load
duke
parents:
diff changeset
6138 void ConcurrentMarkSweepGeneration::update_gc_stats(int current_level,
a61af66fc99e Initial load
duke
parents:
diff changeset
6139 bool full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6140 // The next lower level has been collected. Gather any statistics
a61af66fc99e Initial load
duke
parents:
diff changeset
6141 // that are of interest at this point.
a61af66fc99e Initial load
duke
parents:
diff changeset
6142 if (!full && (current_level + 1) == level()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6143 // Gather statistics on the young generation collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
6144 collector()->stats().record_gc0_end(used());
a61af66fc99e Initial load
duke
parents:
diff changeset
6145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6147
a61af66fc99e Initial load
duke
parents:
diff changeset
6148 CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6149 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
6150 assert(gch->kind() == CollectedHeap::GenCollectedHeap,
a61af66fc99e Initial load
duke
parents:
diff changeset
6151 "Wrong type of heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
6152 CMSAdaptiveSizePolicy* sp = (CMSAdaptiveSizePolicy*)
a61af66fc99e Initial load
duke
parents:
diff changeset
6153 gch->gen_policy()->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
6154 assert(sp->is_gc_cms_adaptive_size_policy(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6155 "Wrong type of size policy");
a61af66fc99e Initial load
duke
parents:
diff changeset
6156 return sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
6157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6158
a61af66fc99e Initial load
duke
parents:
diff changeset
6159 void ConcurrentMarkSweepGeneration::rotate_debug_collection_type() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6160 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6161 gclog_or_tty->print("Rotate from %d ", _debug_collection_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
6162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6163 _debug_collection_type = (CollectionTypes) (_debug_collection_type + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
6164 _debug_collection_type =
a61af66fc99e Initial load
duke
parents:
diff changeset
6165 (CollectionTypes) (_debug_collection_type % Unknown_collection_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
6166 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6167 gclog_or_tty->print_cr("to %d ", _debug_collection_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
6168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6170
a61af66fc99e Initial load
duke
parents:
diff changeset
6171 void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
6172 bool asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6173 // We iterate over the space(s) underlying this generation,
a61af66fc99e Initial load
duke
parents:
diff changeset
6174 // checking the mark bit map to see if the bits corresponding
a61af66fc99e Initial load
duke
parents:
diff changeset
6175 // to specific blocks are marked or not. Blocks that are
a61af66fc99e Initial load
duke
parents:
diff changeset
6176 // marked are live and are not swept up. All remaining blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
6177 // are swept up, with coalescing on-the-fly as we sweep up
a61af66fc99e Initial load
duke
parents:
diff changeset
6178 // contiguous free and/or garbage blocks:
a61af66fc99e Initial load
duke
parents:
diff changeset
6179 // We need to ensure that the sweeper synchronizes with allocators
a61af66fc99e Initial load
duke
parents:
diff changeset
6180 // and stop-the-world collectors. In particular, the following
a61af66fc99e Initial load
duke
parents:
diff changeset
6181 // locks are used:
a61af66fc99e Initial load
duke
parents:
diff changeset
6182 // . CMS token: if this is held, a stop the world collection cannot occur
a61af66fc99e Initial load
duke
parents:
diff changeset
6183 // . freelistLock: if this is held no allocation can occur from this
a61af66fc99e Initial load
duke
parents:
diff changeset
6184 // generation by another thread
a61af66fc99e Initial load
duke
parents:
diff changeset
6185 // . bitMapLock: if this is held, no other thread can access or update
a61af66fc99e Initial load
duke
parents:
diff changeset
6186 //
a61af66fc99e Initial load
duke
parents:
diff changeset
6187
a61af66fc99e Initial load
duke
parents:
diff changeset
6188 // Note that we need to hold the freelistLock if we use
a61af66fc99e Initial load
duke
parents:
diff changeset
6189 // block iterate below; else the iterator might go awry if
a61af66fc99e Initial load
duke
parents:
diff changeset
6190 // a mutator (or promotion) causes block contents to change
a61af66fc99e Initial load
duke
parents:
diff changeset
6191 // (for instance if the allocator divvies up a block).
a61af66fc99e Initial load
duke
parents:
diff changeset
6192 // If we hold the free list lock, for all practical purposes
a61af66fc99e Initial load
duke
parents:
diff changeset
6193 // young generation GC's can't occur (they'll usually need to
a61af66fc99e Initial load
duke
parents:
diff changeset
6194 // promote), so we might as well prevent all young generation
a61af66fc99e Initial load
duke
parents:
diff changeset
6195 // GC's while we do a sweeping step. For the same reason, we might
a61af66fc99e Initial load
duke
parents:
diff changeset
6196 // as well take the bit map lock for the entire duration
a61af66fc99e Initial load
duke
parents:
diff changeset
6197
a61af66fc99e Initial load
duke
parents:
diff changeset
6198 // check that we hold the requisite locks
a61af66fc99e Initial load
duke
parents:
diff changeset
6199 assert(have_cms_token(), "Should hold cms token");
a61af66fc99e Initial load
duke
parents:
diff changeset
6200 assert( (asynch && ConcurrentMarkSweepThread::cms_thread_has_cms_token())
a61af66fc99e Initial load
duke
parents:
diff changeset
6201 || (!asynch && ConcurrentMarkSweepThread::vm_thread_has_cms_token()),
a61af66fc99e Initial load
duke
parents:
diff changeset
6202 "Should possess CMS token to sweep");
a61af66fc99e Initial load
duke
parents:
diff changeset
6203 assert_lock_strong(gen->freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
6204 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
6205
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6206 assert(!_inter_sweep_timer.is_active(), "Was switched off in an outer context");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6207 assert(_intra_sweep_timer.is_active(), "Was switched on in an outer context");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6208 gen->cmsSpace()->beginSweepFLCensus((float)(_inter_sweep_timer.seconds()),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6209 _inter_sweep_estimate.padded_average(),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6210 _intra_sweep_estimate.padded_average());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6211 gen->setNearLargestChunk();
a61af66fc99e Initial load
duke
parents:
diff changeset
6212
a61af66fc99e Initial load
duke
parents:
diff changeset
6213 {
a61af66fc99e Initial load
duke
parents:
diff changeset
6214 SweepClosure sweepClosure(this, gen, &_markBitMap,
a61af66fc99e Initial load
duke
parents:
diff changeset
6215 CMSYield && asynch);
a61af66fc99e Initial load
duke
parents:
diff changeset
6216 gen->cmsSpace()->blk_iterate_careful(&sweepClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
6217 // We need to free-up/coalesce garbage/blocks from a
a61af66fc99e Initial load
duke
parents:
diff changeset
6218 // co-terminal free run. This is done in the SweepClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
6219 // destructor; so, do not remove this scope, else the
a61af66fc99e Initial load
duke
parents:
diff changeset
6220 // end-of-sweep-census below will be off by a little bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
6221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6222 gen->cmsSpace()->sweep_completed();
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 1085
diff changeset
6223 gen->cmsSpace()->endSweepFLCensus(sweep_count());
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
6224 if (should_unload_classes()) { // unloaded classes this cycle,
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
6225 _concurrent_cycles_since_last_unload = 0; // ... reset count
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
6226 } else { // did not unload classes,
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
6227 _concurrent_cycles_since_last_unload++; // ... increment count
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
6228 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6230
a61af66fc99e Initial load
duke
parents:
diff changeset
6231 // Reset CMS data structures (for now just the marking bit map)
a61af66fc99e Initial load
duke
parents:
diff changeset
6232 // preparatory for the next cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
6233 void CMSCollector::reset(bool asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6234 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
6235 CMSAdaptiveSizePolicy* sp = size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
6236 AdaptiveSizePolicyOutput(sp, gch->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
6237 if (asynch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6238 CMSTokenSyncWithLocks ts(true, bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
6239
a61af66fc99e Initial load
duke
parents:
diff changeset
6240 // If the state is not "Resetting", the foreground thread
a61af66fc99e Initial load
duke
parents:
diff changeset
6241 // has done a collection and the resetting.
a61af66fc99e Initial load
duke
parents:
diff changeset
6242 if (_collectorState != Resetting) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6243 assert(_collectorState == Idling, "The state should only change"
a61af66fc99e Initial load
duke
parents:
diff changeset
6244 " because the foreground collector has finished the collection");
a61af66fc99e Initial load
duke
parents:
diff changeset
6245 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6247
a61af66fc99e Initial load
duke
parents:
diff changeset
6248 // Clear the mark bitmap (no grey objects to start with)
a61af66fc99e Initial load
duke
parents:
diff changeset
6249 // for the next cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
6250 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
6251 CMSPhaseAccounting cmspa(this, "reset", !PrintGCDetails);
a61af66fc99e Initial load
duke
parents:
diff changeset
6252
a61af66fc99e Initial load
duke
parents:
diff changeset
6253 HeapWord* curAddr = _markBitMap.startWord();
a61af66fc99e Initial load
duke
parents:
diff changeset
6254 while (curAddr < _markBitMap.endWord()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6255 size_t remaining = pointer_delta(_markBitMap.endWord(), curAddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
6256 MemRegion chunk(curAddr, MIN2(CMSBitMapYieldQuantum, remaining));
a61af66fc99e Initial load
duke
parents:
diff changeset
6257 _markBitMap.clear_large_range(chunk);
a61af66fc99e Initial load
duke
parents:
diff changeset
6258 if (ConcurrentMarkSweepThread::should_yield() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
6259 !foregroundGCIsActive() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
6260 CMSYield) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6261 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6262 "CMS thread should hold CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
6263 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
6264 bitMapLock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
6265 ConcurrentMarkSweepThread::desynchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
6266 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
6267 stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
6268 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6269 incrementYields();
a61af66fc99e Initial load
duke
parents:
diff changeset
6270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6271 icms_wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
6272
a61af66fc99e Initial load
duke
parents:
diff changeset
6273 // See the comment in coordinator_yield()
a61af66fc99e Initial load
duke
parents:
diff changeset
6274 for (unsigned i = 0; i < CMSYieldSleepCount &&
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6275 ConcurrentMarkSweepThread::should_yield() &&
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6276 !CMSCollector::foregroundGCIsActive(); ++i) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6277 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
6278 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
6279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6280
a61af66fc99e Initial load
duke
parents:
diff changeset
6281 ConcurrentMarkSweepThread::synchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
6282 bitMapLock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
6283 startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
6284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6285 curAddr = chunk.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
6286 }
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
6287 // A successful mostly concurrent collection has been done.
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
6288 // Because only the full (i.e., concurrent mode failure) collections
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
6289 // are being measured for gc overhead limits, clean the "near" flag
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
6290 // and count.
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1289
diff changeset
6291 sp->reset_gc_overhead_limit_count();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6292 _collectorState = Idling;
a61af66fc99e Initial load
duke
parents:
diff changeset
6293 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6294 // already have the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
6295 assert(_collectorState == Resetting, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
6296 assert_lock_strong(bitMapLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
6297 _markBitMap.clear_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
6298 _collectorState = Idling;
a61af66fc99e Initial load
duke
parents:
diff changeset
6299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6300
a61af66fc99e Initial load
duke
parents:
diff changeset
6301 // Stop incremental mode after a cycle completes, so that any future cycles
a61af66fc99e Initial load
duke
parents:
diff changeset
6302 // are triggered by allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
6303 stop_icms();
a61af66fc99e Initial load
duke
parents:
diff changeset
6304
a61af66fc99e Initial load
duke
parents:
diff changeset
6305 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
6306 if (RotateCMSCollectionTypes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6307 _cmsGen->rotate_debug_collection_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
6308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6309 )
a61af66fc99e Initial load
duke
parents:
diff changeset
6310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6311
a61af66fc99e Initial load
duke
parents:
diff changeset
6312 void CMSCollector::do_CMS_operation(CMS_op_type op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6313 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
a61af66fc99e Initial load
duke
parents:
diff changeset
6314 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
6315 TraceTime t("GC", PrintGC, !PrintGCDetails, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
6316 TraceCollectorStats tcs(counters());
a61af66fc99e Initial load
duke
parents:
diff changeset
6317
a61af66fc99e Initial load
duke
parents:
diff changeset
6318 switch (op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6319 case CMS_op_checkpointRootsInitial: {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1994
diff changeset
6320 SvcGCMarker sgcm(SvcGCMarker::OTHER);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6321 checkpointRootsInitial(true); // asynch
a61af66fc99e Initial load
duke
parents:
diff changeset
6322 if (PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6323 _cmsGen->printOccupancy("initial-mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
6324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6325 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
6326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6327 case CMS_op_checkpointRootsFinal: {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1994
diff changeset
6328 SvcGCMarker sgcm(SvcGCMarker::OTHER);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6329 checkpointRootsFinal(true, // asynch
a61af66fc99e Initial load
duke
parents:
diff changeset
6330 false, // !clear_all_soft_refs
a61af66fc99e Initial load
duke
parents:
diff changeset
6331 false); // !init_mark_was_synchronous
a61af66fc99e Initial load
duke
parents:
diff changeset
6332 if (PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6333 _cmsGen->printOccupancy("remark");
a61af66fc99e Initial load
duke
parents:
diff changeset
6334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6335 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
6336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6337 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
6338 fatal("No such CMS_op");
a61af66fc99e Initial load
duke
parents:
diff changeset
6339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6341
a61af66fc99e Initial load
duke
parents:
diff changeset
6342 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
6343 size_t const CMSCollector::skip_header_HeapWords() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6344 return FreeChunk::header_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
6345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6346
a61af66fc99e Initial load
duke
parents:
diff changeset
6347 // Try and collect here conditions that should hold when
a61af66fc99e Initial load
duke
parents:
diff changeset
6348 // CMS thread is exiting. The idea is that the foreground GC
a61af66fc99e Initial load
duke
parents:
diff changeset
6349 // thread should not be blocked if it wants to terminate
a61af66fc99e Initial load
duke
parents:
diff changeset
6350 // the CMS thread and yet continue to run the VM for a while
a61af66fc99e Initial load
duke
parents:
diff changeset
6351 // after that.
a61af66fc99e Initial load
duke
parents:
diff changeset
6352 void CMSCollector::verify_ok_to_terminate() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
6353 assert(Thread::current()->is_ConcurrentGC_thread(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6354 "should be called by CMS thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
6355 assert(!_foregroundGCShouldWait, "should be false");
a61af66fc99e Initial load
duke
parents:
diff changeset
6356 // We could check here that all the various low-level locks
a61af66fc99e Initial load
duke
parents:
diff changeset
6357 // are not held by the CMS thread, but that is overkill; see
a61af66fc99e Initial load
duke
parents:
diff changeset
6358 // also CMSThread::verify_ok_to_terminate() where the CGC_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
6359 // is checked.
a61af66fc99e Initial load
duke
parents:
diff changeset
6360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6361 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
6362
a61af66fc99e Initial load
duke
parents:
diff changeset
6363 size_t CMSCollector::block_size_using_printezis_bits(HeapWord* addr) const {
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
6364 assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 452
diff changeset
6365 "missing Printezis mark?");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6366 HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6367 size_t size = pointer_delta(nextOneAddr + 1, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
6368 assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
a61af66fc99e Initial load
duke
parents:
diff changeset
6369 "alignment problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
6370 assert(size >= 3, "Necessary for Printezis marks to work");
a61af66fc99e Initial load
duke
parents:
diff changeset
6371 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
6372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6373
a61af66fc99e Initial load
duke
parents:
diff changeset
6374 // A variant of the above (block_size_using_printezis_bits()) except
a61af66fc99e Initial load
duke
parents:
diff changeset
6375 // that we return 0 if the P-bits are not yet set.
a61af66fc99e Initial load
duke
parents:
diff changeset
6376 size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const {
2226
c5a923563727 6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents: 2177
diff changeset
6377 if (_markBitMap.isMarked(addr + 1)) {
c5a923563727 6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents: 2177
diff changeset
6378 assert(_markBitMap.isMarked(addr), "P-bit can be set only for marked objects");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6379 HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6380 size_t size = pointer_delta(nextOneAddr + 1, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
6381 assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
a61af66fc99e Initial load
duke
parents:
diff changeset
6382 "alignment problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
6383 assert(size >= 3, "Necessary for Printezis marks to work");
a61af66fc99e Initial load
duke
parents:
diff changeset
6384 return size;
2226
c5a923563727 6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents: 2177
diff changeset
6385 }
c5a923563727 6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents: 2177
diff changeset
6386 return 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6388
a61af66fc99e Initial load
duke
parents:
diff changeset
6389 HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
6390 size_t sz = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6391 oop p = (oop)addr;
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
6392 if (p->klass_or_null() != NULL && p->is_parsable()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6393 sz = CompactibleFreeListSpace::adjustObjectSize(p->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
6394 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6395 sz = block_size_using_printezis_bits(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
6396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6397 assert(sz > 0, "size must be nonzero");
a61af66fc99e Initial load
duke
parents:
diff changeset
6398 HeapWord* next_block = addr + sz;
a61af66fc99e Initial load
duke
parents:
diff changeset
6399 HeapWord* next_card = (HeapWord*)round_to((uintptr_t)next_block,
a61af66fc99e Initial load
duke
parents:
diff changeset
6400 CardTableModRefBS::card_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
6401 assert(round_down((uintptr_t)addr, CardTableModRefBS::card_size) <
a61af66fc99e Initial load
duke
parents:
diff changeset
6402 round_down((uintptr_t)next_card, CardTableModRefBS::card_size),
a61af66fc99e Initial load
duke
parents:
diff changeset
6403 "must be different cards");
a61af66fc99e Initial load
duke
parents:
diff changeset
6404 return next_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
6405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6406
a61af66fc99e Initial load
duke
parents:
diff changeset
6407
a61af66fc99e Initial load
duke
parents:
diff changeset
6408 // CMS Bit Map Wrapper /////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
6409
a61af66fc99e Initial load
duke
parents:
diff changeset
6410 // Construct a CMS bit map infrastructure, but don't create the
a61af66fc99e Initial load
duke
parents:
diff changeset
6411 // bit vector itself. That is done by a separate call CMSBitMap::allocate()
a61af66fc99e Initial load
duke
parents:
diff changeset
6412 // further below.
a61af66fc99e Initial load
duke
parents:
diff changeset
6413 CMSBitMap::CMSBitMap(int shifter, int mutex_rank, const char* mutex_name):
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
6414 _bm(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6415 _shifter(shifter),
a61af66fc99e Initial load
duke
parents:
diff changeset
6416 _lock(mutex_rank >= 0 ? new Mutex(mutex_rank, mutex_name, true) : NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
6417 {
a61af66fc99e Initial load
duke
parents:
diff changeset
6418 _bmStartWord = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6419 _bmWordSize = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6421
a61af66fc99e Initial load
duke
parents:
diff changeset
6422 bool CMSBitMap::allocate(MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6423 _bmStartWord = mr.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
6424 _bmWordSize = mr.word_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
6425 ReservedSpace brs(ReservedSpace::allocation_align_size_up(
a61af66fc99e Initial load
duke
parents:
diff changeset
6426 (_bmWordSize >> (_shifter + LogBitsPerByte)) + 1));
a61af66fc99e Initial load
duke
parents:
diff changeset
6427 if (!brs.is_reserved()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6428 warning("CMS bit map allocation failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
6429 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
6430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6431 // For now we'll just commit all of the bit map up fromt.
a61af66fc99e Initial load
duke
parents:
diff changeset
6432 // Later on we'll try to be more parsimonious with swap.
a61af66fc99e Initial load
duke
parents:
diff changeset
6433 if (!_virtual_space.initialize(brs, brs.size())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6434 warning("CMS bit map backing store failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
6435 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
6436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6437 assert(_virtual_space.committed_size() == brs.size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6438 "didn't reserve backing store for all of CMS bit map?");
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
6439 _bm.set_map((BitMap::bm_word_t*)_virtual_space.low());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6440 assert(_virtual_space.committed_size() << (_shifter + LogBitsPerByte) >=
a61af66fc99e Initial load
duke
parents:
diff changeset
6441 _bmWordSize, "inconsistency in bit map sizing");
a61af66fc99e Initial load
duke
parents:
diff changeset
6442 _bm.set_size(_bmWordSize >> _shifter);
a61af66fc99e Initial load
duke
parents:
diff changeset
6443
a61af66fc99e Initial load
duke
parents:
diff changeset
6444 // bm.clear(); // can we rely on getting zero'd memory? verify below
a61af66fc99e Initial load
duke
parents:
diff changeset
6445 assert(isAllClear(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6446 "Expected zero'd memory from ReservedSpace constructor");
a61af66fc99e Initial load
duke
parents:
diff changeset
6447 assert(_bm.size() == heapWordDiffToOffsetDiff(sizeInWords()),
a61af66fc99e Initial load
duke
parents:
diff changeset
6448 "consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
6449 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
6450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6451
a61af66fc99e Initial load
duke
parents:
diff changeset
6452 void CMSBitMap::dirty_range_iterate_clear(MemRegion mr, MemRegionClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6453 HeapWord *next_addr, *end_addr, *last_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
6454 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
6455 assert(covers(mr), "out-of-range error");
a61af66fc99e Initial load
duke
parents:
diff changeset
6456 // XXX assert that start and end are appropriately aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
6457 for (next_addr = mr.start(), end_addr = mr.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
6458 next_addr < end_addr; next_addr = last_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6459 MemRegion dirty_region = getAndClearMarkedRegion(next_addr, end_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
6460 last_addr = dirty_region.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
6461 if (!dirty_region.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6462 cl->do_MemRegion(dirty_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
6463 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6464 assert(last_addr == end_addr, "program logic");
a61af66fc99e Initial load
duke
parents:
diff changeset
6465 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6469
a61af66fc99e Initial load
duke
parents:
diff changeset
6470 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
6471 void CMSBitMap::assert_locked() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
6472 CMSLockVerifier::assert_locked(lock());
a61af66fc99e Initial load
duke
parents:
diff changeset
6473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6474
a61af66fc99e Initial load
duke
parents:
diff changeset
6475 bool CMSBitMap::covers(MemRegion mr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
6476 // assert(_bm.map() == _virtual_space.low(), "map inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
6477 assert((size_t)_bm.size() == (_bmWordSize >> _shifter),
a61af66fc99e Initial load
duke
parents:
diff changeset
6478 "size inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
6479 return (mr.start() >= _bmStartWord) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
6480 (mr.end() <= endWord());
a61af66fc99e Initial load
duke
parents:
diff changeset
6481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6482
a61af66fc99e Initial load
duke
parents:
diff changeset
6483 bool CMSBitMap::covers(HeapWord* start, size_t size) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
6484 return (start >= _bmStartWord && (start + size) <= endWord());
a61af66fc99e Initial load
duke
parents:
diff changeset
6485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6486
a61af66fc99e Initial load
duke
parents:
diff changeset
6487 void CMSBitMap::verifyNoOneBitsInRange(HeapWord* left, HeapWord* right) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6488 // verify that there are no 1 bits in the interval [left, right)
a61af66fc99e Initial load
duke
parents:
diff changeset
6489 FalseBitMapClosure falseBitMapClosure;
a61af66fc99e Initial load
duke
parents:
diff changeset
6490 iterate(&falseBitMapClosure, left, right);
a61af66fc99e Initial load
duke
parents:
diff changeset
6491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6492
a61af66fc99e Initial load
duke
parents:
diff changeset
6493 void CMSBitMap::region_invariant(MemRegion mr)
a61af66fc99e Initial load
duke
parents:
diff changeset
6494 {
a61af66fc99e Initial load
duke
parents:
diff changeset
6495 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
6496 // mr = mr.intersection(MemRegion(_bmStartWord, _bmWordSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
6497 assert(!mr.is_empty(), "unexpected empty region");
a61af66fc99e Initial load
duke
parents:
diff changeset
6498 assert(covers(mr), "mr should be covered by bit map");
a61af66fc99e Initial load
duke
parents:
diff changeset
6499 // convert address range into offset range
a61af66fc99e Initial load
duke
parents:
diff changeset
6500 size_t start_ofs = heapWordToOffset(mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
6501 // Make sure that end() is appropriately aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
6502 assert(mr.end() == (HeapWord*)round_to((intptr_t)mr.end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6503 (1 << (_shifter+LogHeapWordSize))),
a61af66fc99e Initial load
duke
parents:
diff changeset
6504 "Misaligned mr.end()");
a61af66fc99e Initial load
duke
parents:
diff changeset
6505 size_t end_ofs = heapWordToOffset(mr.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
6506 assert(end_ofs > start_ofs, "Should mark at least one bit");
a61af66fc99e Initial load
duke
parents:
diff changeset
6507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6508
a61af66fc99e Initial load
duke
parents:
diff changeset
6509 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
6510
a61af66fc99e Initial load
duke
parents:
diff changeset
6511 bool CMSMarkStack::allocate(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6512 // allocate a stack of the requisite depth
a61af66fc99e Initial load
duke
parents:
diff changeset
6513 ReservedSpace rs(ReservedSpace::allocation_align_size_up(
a61af66fc99e Initial load
duke
parents:
diff changeset
6514 size * sizeof(oop)));
a61af66fc99e Initial load
duke
parents:
diff changeset
6515 if (!rs.is_reserved()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6516 warning("CMSMarkStack allocation failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
6517 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
6518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6519 if (!_virtual_space.initialize(rs, rs.size())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6520 warning("CMSMarkStack backing store failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
6521 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
6522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6523 assert(_virtual_space.committed_size() == rs.size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6524 "didn't reserve backing store for all of CMS stack?");
a61af66fc99e Initial load
duke
parents:
diff changeset
6525 _base = (oop*)(_virtual_space.low());
a61af66fc99e Initial load
duke
parents:
diff changeset
6526 _index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6527 _capacity = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
6528 NOT_PRODUCT(_max_depth = 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
6529 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
6530 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6531
a61af66fc99e Initial load
duke
parents:
diff changeset
6532 // XXX FIX ME !!! In the MT case we come in here holding a
a61af66fc99e Initial load
duke
parents:
diff changeset
6533 // leaf lock. For printing we need to take a further lock
a61af66fc99e Initial load
duke
parents:
diff changeset
6534 // which has lower rank. We need to recallibrate the two
a61af66fc99e Initial load
duke
parents:
diff changeset
6535 // lock-ranks involved in order to be able to rpint the
a61af66fc99e Initial load
duke
parents:
diff changeset
6536 // messages below. (Or defer the printing to the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
6537 // For now we take the expedient path of just disabling the
a61af66fc99e Initial load
duke
parents:
diff changeset
6538 // messages for the problematic case.)
a61af66fc99e Initial load
duke
parents:
diff changeset
6539 void CMSMarkStack::expand() {
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
6540 assert(_capacity <= MarkStackSizeMax, "stack bigger than permitted");
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
6541 if (_capacity == MarkStackSizeMax) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6542 if (_hit_limit++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6543 // We print a warning message only once per CMS cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
6544 gclog_or_tty->print_cr(" (benign) Hit CMSMarkStack max size limit");
a61af66fc99e Initial load
duke
parents:
diff changeset
6545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6546 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6548 // Double capacity if possible
1284
5f1f51edaff6 6928081: G1: rename parameters common with CMS
jmasa
parents: 1190
diff changeset
6549 size_t new_capacity = MIN2(_capacity*2, MarkStackSizeMax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6550 // Do not give up existing stack until we have managed to
a61af66fc99e Initial load
duke
parents:
diff changeset
6551 // get the double capacity that we desired.
a61af66fc99e Initial load
duke
parents:
diff changeset
6552 ReservedSpace rs(ReservedSpace::allocation_align_size_up(
a61af66fc99e Initial load
duke
parents:
diff changeset
6553 new_capacity * sizeof(oop)));
a61af66fc99e Initial load
duke
parents:
diff changeset
6554 if (rs.is_reserved()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6555 // Release the backing store associated with old stack
a61af66fc99e Initial load
duke
parents:
diff changeset
6556 _virtual_space.release();
a61af66fc99e Initial load
duke
parents:
diff changeset
6557 // Reinitialize virtual space for new stack
a61af66fc99e Initial load
duke
parents:
diff changeset
6558 if (!_virtual_space.initialize(rs, rs.size())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6559 fatal("Not enough swap for expanded marking stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
6560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6561 _base = (oop*)(_virtual_space.low());
a61af66fc99e Initial load
duke
parents:
diff changeset
6562 _index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6563 _capacity = new_capacity;
a61af66fc99e Initial load
duke
parents:
diff changeset
6564 } else if (_failed_double++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6565 // Failed to double capacity, continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
6566 // we print a detail message only once per CMS cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
6567 gclog_or_tty->print(" (benign) Failed to expand marking stack from "SIZE_FORMAT"K to "
a61af66fc99e Initial load
duke
parents:
diff changeset
6568 SIZE_FORMAT"K",
a61af66fc99e Initial load
duke
parents:
diff changeset
6569 _capacity / K, new_capacity / K);
a61af66fc99e Initial load
duke
parents:
diff changeset
6570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6572
a61af66fc99e Initial load
duke
parents:
diff changeset
6573
a61af66fc99e Initial load
duke
parents:
diff changeset
6574 // Closures
a61af66fc99e Initial load
duke
parents:
diff changeset
6575 // XXX: there seems to be a lot of code duplication here;
a61af66fc99e Initial load
duke
parents:
diff changeset
6576 // should refactor and consolidate common code.
a61af66fc99e Initial load
duke
parents:
diff changeset
6577
a61af66fc99e Initial load
duke
parents:
diff changeset
6578 // This closure is used to mark refs into the CMS generation in
a61af66fc99e Initial load
duke
parents:
diff changeset
6579 // the CMS bit map. Called at the first checkpoint. This closure
a61af66fc99e Initial load
duke
parents:
diff changeset
6580 // assumes that we do not need to re-mark dirty cards; if the CMS
a61af66fc99e Initial load
duke
parents:
diff changeset
6581 // generation on which this is used is not an oldest (modulo perm gen)
a61af66fc99e Initial load
duke
parents:
diff changeset
6582 // generation then this will lose younger_gen cards!
a61af66fc99e Initial load
duke
parents:
diff changeset
6583
a61af66fc99e Initial load
duke
parents:
diff changeset
6584 MarkRefsIntoClosure::MarkRefsIntoClosure(
994
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
6585 MemRegion span, CMSBitMap* bitMap):
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6586 _span(span),
994
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
6587 _bitMap(bitMap)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6588 {
a61af66fc99e Initial load
duke
parents:
diff changeset
6589 assert(_ref_processor == NULL, "deliberately left NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
6590 assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
6591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6592
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6593 void MarkRefsIntoClosure::do_oop(oop obj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6594 // if p points into _span, then mark corresponding bit in _markBitMap
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6595 assert(obj->is_oop(), "expected an oop");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6596 HeapWord* addr = (HeapWord*)obj;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6597 if (_span.contains(addr)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6598 // this should be made more efficient
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6599 _bitMap->mark(addr);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6600 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6601 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6602
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6603 void MarkRefsIntoClosure::do_oop(oop* p) { MarkRefsIntoClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6604 void MarkRefsIntoClosure::do_oop(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6605
a61af66fc99e Initial load
duke
parents:
diff changeset
6606 // A variant of the above, used for CMS marking verification.
a61af66fc99e Initial load
duke
parents:
diff changeset
6607 MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
994
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
6608 MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm):
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6609 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
6610 _verification_bm(verification_bm),
994
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
6611 _cms_bm(cms_bm)
753cf9794df9 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 993
diff changeset
6612 {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6613 assert(_ref_processor == NULL, "deliberately left NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
6614 assert(_verification_bm->covers(_span), "_verification_bm/_span mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
6615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6616
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6617 void MarkRefsIntoVerifyClosure::do_oop(oop obj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6618 // if p points into _span, then mark corresponding bit in _markBitMap
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6619 assert(obj->is_oop(), "expected an oop");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6620 HeapWord* addr = (HeapWord*)obj;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6621 if (_span.contains(addr)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6622 _verification_bm->mark(addr);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6623 if (!_cms_bm->isMarked(addr)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6624 oop(addr)->print();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6625 gclog_or_tty->print_cr(" (" INTPTR_FORMAT " should have been marked)", addr);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6626 fatal("... aborting");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6627 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6628 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6629 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6630
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6631 void MarkRefsIntoVerifyClosure::do_oop(oop* p) { MarkRefsIntoVerifyClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6632 void MarkRefsIntoVerifyClosure::do_oop(narrowOop* p) { MarkRefsIntoVerifyClosure::do_oop_work(p); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6633
a61af66fc99e Initial load
duke
parents:
diff changeset
6634 //////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
6635 // MarkRefsIntoAndScanClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
6636 //////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
6637
a61af66fc99e Initial load
duke
parents:
diff changeset
6638 MarkRefsIntoAndScanClosure::MarkRefsIntoAndScanClosure(MemRegion span,
a61af66fc99e Initial load
duke
parents:
diff changeset
6639 ReferenceProcessor* rp,
a61af66fc99e Initial load
duke
parents:
diff changeset
6640 CMSBitMap* bit_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
6641 CMSBitMap* mod_union_table,
a61af66fc99e Initial load
duke
parents:
diff changeset
6642 CMSMarkStack* mark_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
6643 CMSMarkStack* revisit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
6644 CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
6645 bool should_yield,
a61af66fc99e Initial load
duke
parents:
diff changeset
6646 bool concurrent_precleaning):
a61af66fc99e Initial load
duke
parents:
diff changeset
6647 _collector(collector),
a61af66fc99e Initial load
duke
parents:
diff changeset
6648 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
6649 _bit_map(bit_map),
a61af66fc99e Initial load
duke
parents:
diff changeset
6650 _mark_stack(mark_stack),
a61af66fc99e Initial load
duke
parents:
diff changeset
6651 _pushAndMarkClosure(collector, span, rp, bit_map, mod_union_table,
a61af66fc99e Initial load
duke
parents:
diff changeset
6652 mark_stack, revisit_stack, concurrent_precleaning),
a61af66fc99e Initial load
duke
parents:
diff changeset
6653 _yield(should_yield),
a61af66fc99e Initial load
duke
parents:
diff changeset
6654 _concurrent_precleaning(concurrent_precleaning),
a61af66fc99e Initial load
duke
parents:
diff changeset
6655 _freelistLock(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
6656 {
a61af66fc99e Initial load
duke
parents:
diff changeset
6657 _ref_processor = rp;
a61af66fc99e Initial load
duke
parents:
diff changeset
6658 assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
6659 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6660
a61af66fc99e Initial load
duke
parents:
diff changeset
6661 // This closure is used to mark refs into the CMS generation at the
a61af66fc99e Initial load
duke
parents:
diff changeset
6662 // second (final) checkpoint, and to scan and transitively follow
a61af66fc99e Initial load
duke
parents:
diff changeset
6663 // the unmarked oops. It is also used during the concurrent precleaning
a61af66fc99e Initial load
duke
parents:
diff changeset
6664 // phase while scanning objects on dirty cards in the CMS generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
6665 // The marks are made in the marking bit map and the marking stack is
a61af66fc99e Initial load
duke
parents:
diff changeset
6666 // used for keeping the (newly) grey objects during the scan.
a61af66fc99e Initial load
duke
parents:
diff changeset
6667 // The parallel version (Par_...) appears further below.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6668 void MarkRefsIntoAndScanClosure::do_oop(oop obj) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6669 if (obj != NULL) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6670 assert(obj->is_oop(), "expected an oop");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6671 HeapWord* addr = (HeapWord*)obj;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6672 assert(_mark_stack->isEmpty(), "pre-condition (eager drainage)");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6673 assert(_collector->overflow_list_is_empty(),
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6674 "overflow list should be empty");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6675 if (_span.contains(addr) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
6676 !_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6677 // mark bit map (object is now grey)
a61af66fc99e Initial load
duke
parents:
diff changeset
6678 _bit_map->mark(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
6679 // push on marking stack (stack should be empty), and drain the
a61af66fc99e Initial load
duke
parents:
diff changeset
6680 // stack by applying this closure to the oops in the oops popped
a61af66fc99e Initial load
duke
parents:
diff changeset
6681 // from the stack (i.e. blacken the grey objects)
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6682 bool res = _mark_stack->push(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6683 assert(res, "Should have space to push on empty stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
6684 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
6685 oop new_oop = _mark_stack->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
6686 assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
6687 assert(new_oop->is_parsable(), "Found unparsable oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
6688 assert(_bit_map->isMarked((HeapWord*)new_oop),
a61af66fc99e Initial load
duke
parents:
diff changeset
6689 "only grey objects on this stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
6690 // iterate over the oops in this oop, marking and pushing
a61af66fc99e Initial load
duke
parents:
diff changeset
6691 // the ones in CMS heap (i.e. in _span).
a61af66fc99e Initial load
duke
parents:
diff changeset
6692 new_oop->oop_iterate(&_pushAndMarkClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
6693 // check if it's time to yield
a61af66fc99e Initial load
duke
parents:
diff changeset
6694 do_yield_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
6695 } while (!_mark_stack->isEmpty() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
6696 (!_concurrent_precleaning && take_from_overflow_list()));
a61af66fc99e Initial load
duke
parents:
diff changeset
6697 // if marking stack is empty, and we are not doing this
a61af66fc99e Initial load
duke
parents:
diff changeset
6698 // during precleaning, then check the overflow list
a61af66fc99e Initial load
duke
parents:
diff changeset
6699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6700 assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
a61af66fc99e Initial load
duke
parents:
diff changeset
6701 assert(_collector->overflow_list_is_empty(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6702 "overflow list was drained above");
a61af66fc99e Initial load
duke
parents:
diff changeset
6703 // We could restore evacuated mark words, if any, used for
a61af66fc99e Initial load
duke
parents:
diff changeset
6704 // overflow list links here because the overflow list is
a61af66fc99e Initial load
duke
parents:
diff changeset
6705 // provably empty here. That would reduce the maximum
a61af66fc99e Initial load
duke
parents:
diff changeset
6706 // size requirements for preserved_{oop,mark}_stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
6707 // But we'll just postpone it until we are all done
a61af66fc99e Initial load
duke
parents:
diff changeset
6708 // so we can just stream through.
a61af66fc99e Initial load
duke
parents:
diff changeset
6709 if (!_concurrent_precleaning && CMSOverflowEarlyRestoration) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6710 _collector->restore_preserved_marks_if_any();
a61af66fc99e Initial load
duke
parents:
diff changeset
6711 assert(_collector->no_preserved_marks(), "No preserved marks");
a61af66fc99e Initial load
duke
parents:
diff changeset
6712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6713 assert(!CMSOverflowEarlyRestoration || _collector->no_preserved_marks(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6714 "All preserved marks should have been restored above");
a61af66fc99e Initial load
duke
parents:
diff changeset
6715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6717
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6718 void MarkRefsIntoAndScanClosure::do_oop(oop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6719 void MarkRefsIntoAndScanClosure::do_oop(narrowOop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6720
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6721 void MarkRefsIntoAndScanClosure::do_yield_work() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6722 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6723 "CMS thread should hold CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
6724 assert_lock_strong(_freelistLock);
a61af66fc99e Initial load
duke
parents:
diff changeset
6725 assert_lock_strong(_bit_map->lock());
a61af66fc99e Initial load
duke
parents:
diff changeset
6726 // relinquish the free_list_lock and bitMaplock()
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
6727 DEBUG_ONLY(RememberKlassesChecker mux(false);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6728 _bit_map->lock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
6729 _freelistLock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
6730 ConcurrentMarkSweepThread::desynchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
6731 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
6732 _collector->stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
6733 GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
a61af66fc99e Initial load
duke
parents:
diff changeset
6734 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6735 _collector->incrementYields();
a61af66fc99e Initial load
duke
parents:
diff changeset
6736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6737 _collector->icms_wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
6738
a61af66fc99e Initial load
duke
parents:
diff changeset
6739 // See the comment in coordinator_yield()
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6740 for (unsigned i = 0;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6741 i < CMSYieldSleepCount &&
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6742 ConcurrentMarkSweepThread::should_yield() &&
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6743 !CMSCollector::foregroundGCIsActive();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6744 ++i) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6745 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
6746 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
6747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6748
a61af66fc99e Initial load
duke
parents:
diff changeset
6749 ConcurrentMarkSweepThread::synchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
6750 _freelistLock->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
6751 _bit_map->lock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
6752 _collector->startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
6753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6754
a61af66fc99e Initial load
duke
parents:
diff changeset
6755 ///////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
6756 // Par_MarkRefsIntoAndScanClosure: a parallel version of
a61af66fc99e Initial load
duke
parents:
diff changeset
6757 // MarkRefsIntoAndScanClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
6758 ///////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
6759 Par_MarkRefsIntoAndScanClosure::Par_MarkRefsIntoAndScanClosure(
a61af66fc99e Initial load
duke
parents:
diff changeset
6760 CMSCollector* collector, MemRegion span, ReferenceProcessor* rp,
a61af66fc99e Initial load
duke
parents:
diff changeset
6761 CMSBitMap* bit_map, OopTaskQueue* work_queue, CMSMarkStack* revisit_stack):
a61af66fc99e Initial load
duke
parents:
diff changeset
6762 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
6763 _bit_map(bit_map),
a61af66fc99e Initial load
duke
parents:
diff changeset
6764 _work_queue(work_queue),
a61af66fc99e Initial load
duke
parents:
diff changeset
6765 _low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
a61af66fc99e Initial load
duke
parents:
diff changeset
6766 (uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads))),
a61af66fc99e Initial load
duke
parents:
diff changeset
6767 _par_pushAndMarkClosure(collector, span, rp, bit_map, work_queue,
a61af66fc99e Initial load
duke
parents:
diff changeset
6768 revisit_stack)
a61af66fc99e Initial load
duke
parents:
diff changeset
6769 {
a61af66fc99e Initial load
duke
parents:
diff changeset
6770 _ref_processor = rp;
a61af66fc99e Initial load
duke
parents:
diff changeset
6771 assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
6772 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6773
a61af66fc99e Initial load
duke
parents:
diff changeset
6774 // This closure is used to mark refs into the CMS generation at the
a61af66fc99e Initial load
duke
parents:
diff changeset
6775 // second (final) checkpoint, and to scan and transitively follow
a61af66fc99e Initial load
duke
parents:
diff changeset
6776 // the unmarked oops. The marks are made in the marking bit map and
a61af66fc99e Initial load
duke
parents:
diff changeset
6777 // the work_queue is used for keeping the (newly) grey objects during
a61af66fc99e Initial load
duke
parents:
diff changeset
6778 // the scan phase whence they are also available for stealing by parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
6779 // threads. Since the marking bit map is shared, updates are
a61af66fc99e Initial load
duke
parents:
diff changeset
6780 // synchronized (via CAS).
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6781 void Par_MarkRefsIntoAndScanClosure::do_oop(oop obj) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6782 if (obj != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6783 // Ignore mark word because this could be an already marked oop
a61af66fc99e Initial load
duke
parents:
diff changeset
6784 // that may be chained at the end of the overflow list.
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
6785 assert(obj->is_oop(true), "expected an oop");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6786 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6787 if (_span.contains(addr) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
6788 !_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6789 // mark bit map (object will become grey):
a61af66fc99e Initial load
duke
parents:
diff changeset
6790 // It is possible for several threads to be
a61af66fc99e Initial load
duke
parents:
diff changeset
6791 // trying to "claim" this object concurrently;
a61af66fc99e Initial load
duke
parents:
diff changeset
6792 // the unique thread that succeeds in marking the
a61af66fc99e Initial load
duke
parents:
diff changeset
6793 // object first will do the subsequent push on
a61af66fc99e Initial load
duke
parents:
diff changeset
6794 // to the work queue (or overflow list).
a61af66fc99e Initial load
duke
parents:
diff changeset
6795 if (_bit_map->par_mark(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6796 // push on work_queue (which may not be empty), and trim the
a61af66fc99e Initial load
duke
parents:
diff changeset
6797 // queue to an appropriate length by applying this closure to
a61af66fc99e Initial load
duke
parents:
diff changeset
6798 // the oops in the oops popped from the stack (i.e. blacken the
a61af66fc99e Initial load
duke
parents:
diff changeset
6799 // grey objects)
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6800 bool res = _work_queue->push(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6801 assert(res, "Low water mark should be less than capacity?");
a61af66fc99e Initial load
duke
parents:
diff changeset
6802 trim_queue(_low_water_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
6803 } // Else, another thread claimed the object
a61af66fc99e Initial load
duke
parents:
diff changeset
6804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6805 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6807
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6808 void Par_MarkRefsIntoAndScanClosure::do_oop(oop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6809 void Par_MarkRefsIntoAndScanClosure::do_oop(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6810
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6811 // This closure is used to rescan the marked objects on the dirty cards
a61af66fc99e Initial load
duke
parents:
diff changeset
6812 // in the mod union table and the card table proper.
a61af66fc99e Initial load
duke
parents:
diff changeset
6813 size_t ScanMarkedObjectsAgainCarefullyClosure::do_object_careful_m(
a61af66fc99e Initial load
duke
parents:
diff changeset
6814 oop p, MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6815
a61af66fc99e Initial load
duke
parents:
diff changeset
6816 size_t size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6817 HeapWord* addr = (HeapWord*)p;
a61af66fc99e Initial load
duke
parents:
diff changeset
6818 DEBUG_ONLY(_collector->verify_work_stacks_empty();)
a61af66fc99e Initial load
duke
parents:
diff changeset
6819 assert(_span.contains(addr), "we are scanning the CMS generation");
a61af66fc99e Initial load
duke
parents:
diff changeset
6820 // check if it's time to yield
a61af66fc99e Initial load
duke
parents:
diff changeset
6821 if (do_yield_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6822 // We yielded for some foreground stop-world work,
a61af66fc99e Initial load
duke
parents:
diff changeset
6823 // and we have been asked to abort this ongoing preclean cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
6824 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6826 if (_bitMap->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6827 // it's marked; is it potentially uninitialized?
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
6828 if (p->klass_or_null() != NULL) {
518
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
6829 // If is_conc_safe is false, the object may be undergoing
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
6830 // change by the VM outside a safepoint. Don't try to
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
6831 // scan it, but rather leave it for the remark phase.
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
6832 if (CMSPermGenPrecleaningEnabled &&
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
6833 (!p->is_conc_safe() || !p->is_parsable())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6834 // Signal precleaning to redirty the card since
a61af66fc99e Initial load
duke
parents:
diff changeset
6835 // the klass pointer is already installed.
a61af66fc99e Initial load
duke
parents:
diff changeset
6836 assert(size == 0, "Initial value");
a61af66fc99e Initial load
duke
parents:
diff changeset
6837 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6838 assert(p->is_parsable(), "must be parsable.");
a61af66fc99e Initial load
duke
parents:
diff changeset
6839 // an initialized object; ignore mark word in verification below
a61af66fc99e Initial load
duke
parents:
diff changeset
6840 // since we are running concurrent with mutators
a61af66fc99e Initial load
duke
parents:
diff changeset
6841 assert(p->is_oop(true), "should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
6842 if (p->is_objArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6843 // objArrays are precisely marked; restrict scanning
a61af66fc99e Initial load
duke
parents:
diff changeset
6844 // to dirty cards only.
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
6845 size = CompactibleFreeListSpace::adjustObjectSize(
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
6846 p->oop_iterate(_scanningClosure, mr));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6847 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6848 // A non-array may have been imprecisely marked; we need
a61af66fc99e Initial load
duke
parents:
diff changeset
6849 // to scan object in its entirety.
a61af66fc99e Initial load
duke
parents:
diff changeset
6850 size = CompactibleFreeListSpace::adjustObjectSize(
a61af66fc99e Initial load
duke
parents:
diff changeset
6851 p->oop_iterate(_scanningClosure));
a61af66fc99e Initial load
duke
parents:
diff changeset
6852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6853 #ifdef DEBUG
a61af66fc99e Initial load
duke
parents:
diff changeset
6854 size_t direct_size =
a61af66fc99e Initial load
duke
parents:
diff changeset
6855 CompactibleFreeListSpace::adjustObjectSize(p->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
6856 assert(size == direct_size, "Inconsistency in size");
a61af66fc99e Initial load
duke
parents:
diff changeset
6857 assert(size >= 3, "Necessary for Printezis marks to work");
a61af66fc99e Initial load
duke
parents:
diff changeset
6858 if (!_bitMap->isMarked(addr+1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6859 _bitMap->verifyNoOneBitsInRange(addr+2, addr+size);
a61af66fc99e Initial load
duke
parents:
diff changeset
6860 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6861 _bitMap->verifyNoOneBitsInRange(addr+2, addr+size-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
6862 assert(_bitMap->isMarked(addr+size-1),
a61af66fc99e Initial load
duke
parents:
diff changeset
6863 "inconsistent Printezis mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
6864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6865 #endif // DEBUG
a61af66fc99e Initial load
duke
parents:
diff changeset
6866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6867 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6868 // an unitialized object
a61af66fc99e Initial load
duke
parents:
diff changeset
6869 assert(_bitMap->isMarked(addr+1), "missing Printezis mark?");
a61af66fc99e Initial load
duke
parents:
diff changeset
6870 HeapWord* nextOneAddr = _bitMap->getNextMarkedWordAddress(addr + 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
6871 size = pointer_delta(nextOneAddr + 1, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
6872 assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
a61af66fc99e Initial load
duke
parents:
diff changeset
6873 "alignment problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
6874 // Note that pre-cleaning needn't redirty the card. OopDesc::set_klass()
a61af66fc99e Initial load
duke
parents:
diff changeset
6875 // will dirty the card when the klass pointer is installed in the
a61af66fc99e Initial load
duke
parents:
diff changeset
6876 // object (signalling the completion of initialization).
a61af66fc99e Initial load
duke
parents:
diff changeset
6877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6878 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6879 // Either a not yet marked object or an uninitialized object
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
6880 if (p->klass_or_null() == NULL || !p->is_parsable()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6881 // An uninitialized object, skip to the next card, since
a61af66fc99e Initial load
duke
parents:
diff changeset
6882 // we may not be able to read its P-bits yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
6883 assert(size == 0, "Initial value");
a61af66fc99e Initial load
duke
parents:
diff changeset
6884 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6885 // An object not (yet) reached by marking: we merely need to
a61af66fc99e Initial load
duke
parents:
diff changeset
6886 // compute its size so as to go look at the next block.
a61af66fc99e Initial load
duke
parents:
diff changeset
6887 assert(p->is_oop(true), "should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
6888 size = CompactibleFreeListSpace::adjustObjectSize(p->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
6889 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6891 DEBUG_ONLY(_collector->verify_work_stacks_empty();)
a61af66fc99e Initial load
duke
parents:
diff changeset
6892 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
6893 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6894
a61af66fc99e Initial load
duke
parents:
diff changeset
6895 void ScanMarkedObjectsAgainCarefullyClosure::do_yield_work() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6896 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6897 "CMS thread should hold CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
6898 assert_lock_strong(_freelistLock);
a61af66fc99e Initial load
duke
parents:
diff changeset
6899 assert_lock_strong(_bitMap->lock());
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
6900 DEBUG_ONLY(RememberKlassesChecker mux(false);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6901 // relinquish the free_list_lock and bitMaplock()
a61af66fc99e Initial load
duke
parents:
diff changeset
6902 _bitMap->lock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
6903 _freelistLock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
6904 ConcurrentMarkSweepThread::desynchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
6905 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
6906 _collector->stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
6907 GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
a61af66fc99e Initial load
duke
parents:
diff changeset
6908 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6909 _collector->incrementYields();
a61af66fc99e Initial load
duke
parents:
diff changeset
6910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6911 _collector->icms_wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
6912
a61af66fc99e Initial load
duke
parents:
diff changeset
6913 // See the comment in coordinator_yield()
a61af66fc99e Initial load
duke
parents:
diff changeset
6914 for (unsigned i = 0; i < CMSYieldSleepCount &&
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6915 ConcurrentMarkSweepThread::should_yield() &&
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
6916 !CMSCollector::foregroundGCIsActive(); ++i) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6917 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
6918 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
6919 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6920
a61af66fc99e Initial load
duke
parents:
diff changeset
6921 ConcurrentMarkSweepThread::synchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
6922 _freelistLock->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
6923 _bitMap->lock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
6924 _collector->startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
6925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6926
a61af66fc99e Initial load
duke
parents:
diff changeset
6927
a61af66fc99e Initial load
duke
parents:
diff changeset
6928 //////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
6929 // SurvivorSpacePrecleanClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
6930 //////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
6931 // This (single-threaded) closure is used to preclean the oops in
a61af66fc99e Initial load
duke
parents:
diff changeset
6932 // the survivor spaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
6933 size_t SurvivorSpacePrecleanClosure::do_object_careful(oop p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6934
a61af66fc99e Initial load
duke
parents:
diff changeset
6935 HeapWord* addr = (HeapWord*)p;
a61af66fc99e Initial load
duke
parents:
diff changeset
6936 DEBUG_ONLY(_collector->verify_work_stacks_empty();)
a61af66fc99e Initial load
duke
parents:
diff changeset
6937 assert(!_span.contains(addr), "we are scanning the survivor spaces");
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
6938 assert(p->klass_or_null() != NULL, "object should be initializd");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6939 assert(p->is_parsable(), "must be parsable.");
a61af66fc99e Initial load
duke
parents:
diff changeset
6940 // an initialized object; ignore mark word in verification below
a61af66fc99e Initial load
duke
parents:
diff changeset
6941 // since we are running concurrent with mutators
a61af66fc99e Initial load
duke
parents:
diff changeset
6942 assert(p->is_oop(true), "should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
6943 // Note that we do not yield while we iterate over
a61af66fc99e Initial load
duke
parents:
diff changeset
6944 // the interior oops of p, pushing the relevant ones
a61af66fc99e Initial load
duke
parents:
diff changeset
6945 // on our marking stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
6946 size_t size = p->oop_iterate(_scanning_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
6947 do_yield_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
6948 // Observe that below, we do not abandon the preclean
a61af66fc99e Initial load
duke
parents:
diff changeset
6949 // phase as soon as we should; rather we empty the
a61af66fc99e Initial load
duke
parents:
diff changeset
6950 // marking stack before returning. This is to satisfy
a61af66fc99e Initial load
duke
parents:
diff changeset
6951 // some existing assertions. In general, it may be a
a61af66fc99e Initial load
duke
parents:
diff changeset
6952 // good idea to abort immediately and complete the marking
a61af66fc99e Initial load
duke
parents:
diff changeset
6953 // from the grey objects at a later time.
a61af66fc99e Initial load
duke
parents:
diff changeset
6954 while (!_mark_stack->isEmpty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6955 oop new_oop = _mark_stack->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
6956 assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
6957 assert(new_oop->is_parsable(), "Found unparsable oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
6958 assert(_bit_map->isMarked((HeapWord*)new_oop),
a61af66fc99e Initial load
duke
parents:
diff changeset
6959 "only grey objects on this stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
6960 // iterate over the oops in this oop, marking and pushing
a61af66fc99e Initial load
duke
parents:
diff changeset
6961 // the ones in CMS heap (i.e. in _span).
a61af66fc99e Initial load
duke
parents:
diff changeset
6962 new_oop->oop_iterate(_scanning_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
6963 // check if it's time to yield
a61af66fc99e Initial load
duke
parents:
diff changeset
6964 do_yield_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
6965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6966 unsigned int after_count =
a61af66fc99e Initial load
duke
parents:
diff changeset
6967 GenCollectedHeap::heap()->total_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
6968 bool abort = (_before_count != after_count) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
6969 _collector->should_abort_preclean();
a61af66fc99e Initial load
duke
parents:
diff changeset
6970 return abort ? 0 : size;
a61af66fc99e Initial load
duke
parents:
diff changeset
6971 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6972
a61af66fc99e Initial load
duke
parents:
diff changeset
6973 void SurvivorSpacePrecleanClosure::do_yield_work() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6974 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
6975 "CMS thread should hold CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
6976 assert_lock_strong(_bit_map->lock());
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
6977 DEBUG_ONLY(RememberKlassesChecker smx(false);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6978 // Relinquish the bit map lock
a61af66fc99e Initial load
duke
parents:
diff changeset
6979 _bit_map->lock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
6980 ConcurrentMarkSweepThread::desynchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
6981 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
6982 _collector->stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
6983 GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
a61af66fc99e Initial load
duke
parents:
diff changeset
6984 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6985 _collector->incrementYields();
a61af66fc99e Initial load
duke
parents:
diff changeset
6986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6987 _collector->icms_wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
6988
a61af66fc99e Initial load
duke
parents:
diff changeset
6989 // See the comment in coordinator_yield()
a61af66fc99e Initial load
duke
parents:
diff changeset
6990 for (unsigned i = 0; i < CMSYieldSleepCount &&
a61af66fc99e Initial load
duke
parents:
diff changeset
6991 ConcurrentMarkSweepThread::should_yield() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
6992 !CMSCollector::foregroundGCIsActive(); ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6993 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
6994 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
6995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6996
a61af66fc99e Initial load
duke
parents:
diff changeset
6997 ConcurrentMarkSweepThread::synchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
6998 _bit_map->lock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
6999 _collector->startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
7000 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7001
a61af66fc99e Initial load
duke
parents:
diff changeset
7002 // This closure is used to rescan the marked objects on the dirty cards
a61af66fc99e Initial load
duke
parents:
diff changeset
7003 // in the mod union table and the card table proper. In the parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
7004 // case, although the bitMap is shared, we do a single read so the
a61af66fc99e Initial load
duke
parents:
diff changeset
7005 // isMarked() query is "safe".
a61af66fc99e Initial load
duke
parents:
diff changeset
7006 bool ScanMarkedObjectsAgainClosure::do_object_bm(oop p, MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7007 // Ignore mark word because we are running concurrent with mutators
a61af66fc99e Initial load
duke
parents:
diff changeset
7008 assert(p->is_oop_or_null(true), "expected an oop or null");
a61af66fc99e Initial load
duke
parents:
diff changeset
7009 HeapWord* addr = (HeapWord*)p;
a61af66fc99e Initial load
duke
parents:
diff changeset
7010 assert(_span.contains(addr), "we are scanning the CMS generation");
a61af66fc99e Initial load
duke
parents:
diff changeset
7011 bool is_obj_array = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
7012 #ifdef DEBUG
a61af66fc99e Initial load
duke
parents:
diff changeset
7013 if (!_parallel) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7014 assert(_mark_stack->isEmpty(), "pre-condition (eager drainage)");
a61af66fc99e Initial load
duke
parents:
diff changeset
7015 assert(_collector->overflow_list_is_empty(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7016 "overflow list should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
7017
a61af66fc99e Initial load
duke
parents:
diff changeset
7018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7019 #endif // DEBUG
a61af66fc99e Initial load
duke
parents:
diff changeset
7020 if (_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7021 // Obj arrays are precisely marked, non-arrays are not;
a61af66fc99e Initial load
duke
parents:
diff changeset
7022 // so we scan objArrays precisely and non-arrays in their
a61af66fc99e Initial load
duke
parents:
diff changeset
7023 // entirety.
a61af66fc99e Initial load
duke
parents:
diff changeset
7024 if (p->is_objArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7025 is_obj_array = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
7026 if (_parallel) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7027 p->oop_iterate(_par_scan_closure, mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7028 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
7029 p->oop_iterate(_scan_closure, mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7031 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
7032 if (_parallel) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7033 p->oop_iterate(_par_scan_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
7034 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
7035 p->oop_iterate(_scan_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
7036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7039 #ifdef DEBUG
a61af66fc99e Initial load
duke
parents:
diff changeset
7040 if (!_parallel) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7041 assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
a61af66fc99e Initial load
duke
parents:
diff changeset
7042 assert(_collector->overflow_list_is_empty(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7043 "overflow list should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
7044
a61af66fc99e Initial load
duke
parents:
diff changeset
7045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7046 #endif // DEBUG
a61af66fc99e Initial load
duke
parents:
diff changeset
7047 return is_obj_array;
a61af66fc99e Initial load
duke
parents:
diff changeset
7048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7049
a61af66fc99e Initial load
duke
parents:
diff changeset
7050 MarkFromRootsClosure::MarkFromRootsClosure(CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
7051 MemRegion span,
a61af66fc99e Initial load
duke
parents:
diff changeset
7052 CMSBitMap* bitMap, CMSMarkStack* markStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7053 CMSMarkStack* revisitStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7054 bool should_yield, bool verifying):
a61af66fc99e Initial load
duke
parents:
diff changeset
7055 _collector(collector),
a61af66fc99e Initial load
duke
parents:
diff changeset
7056 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
7057 _bitMap(bitMap),
a61af66fc99e Initial load
duke
parents:
diff changeset
7058 _mut(&collector->_modUnionTable),
a61af66fc99e Initial load
duke
parents:
diff changeset
7059 _markStack(markStack),
a61af66fc99e Initial load
duke
parents:
diff changeset
7060 _revisitStack(revisitStack),
a61af66fc99e Initial load
duke
parents:
diff changeset
7061 _yield(should_yield),
a61af66fc99e Initial load
duke
parents:
diff changeset
7062 _skipBits(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
7063 {
a61af66fc99e Initial load
duke
parents:
diff changeset
7064 assert(_markStack->isEmpty(), "stack should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
7065 _finger = _bitMap->startWord();
a61af66fc99e Initial load
duke
parents:
diff changeset
7066 _threshold = _finger;
a61af66fc99e Initial load
duke
parents:
diff changeset
7067 assert(_collector->_restart_addr == NULL, "Sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
7068 assert(_span.contains(_finger), "Out of bounds _finger?");
a61af66fc99e Initial load
duke
parents:
diff changeset
7069 DEBUG_ONLY(_verifying = verifying;)
a61af66fc99e Initial load
duke
parents:
diff changeset
7070 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7071
a61af66fc99e Initial load
duke
parents:
diff changeset
7072 void MarkFromRootsClosure::reset(HeapWord* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7073 assert(_markStack->isEmpty(), "would cause duplicates on stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
7074 assert(_span.contains(addr), "Out of bounds _finger?");
a61af66fc99e Initial load
duke
parents:
diff changeset
7075 _finger = addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
7076 _threshold = (HeapWord*)round_to(
a61af66fc99e Initial load
duke
parents:
diff changeset
7077 (intptr_t)_finger, CardTableModRefBS::card_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
7078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7079
a61af66fc99e Initial load
duke
parents:
diff changeset
7080 // Should revisit to see if this should be restructured for
a61af66fc99e Initial load
duke
parents:
diff changeset
7081 // greater efficiency.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7082 bool MarkFromRootsClosure::do_bit(size_t offset) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7083 if (_skipBits > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7084 _skipBits--;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7085 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7087 // convert offset into a HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
7088 HeapWord* addr = _bitMap->startWord() + offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
7089 assert(_bitMap->endWord() && addr < _bitMap->endWord(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7090 "address out of range");
a61af66fc99e Initial load
duke
parents:
diff changeset
7091 assert(_bitMap->isMarked(addr), "tautology");
a61af66fc99e Initial load
duke
parents:
diff changeset
7092 if (_bitMap->isMarked(addr+1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7093 // this is an allocated but not yet initialized object
a61af66fc99e Initial load
duke
parents:
diff changeset
7094 assert(_skipBits == 0, "tautology");
a61af66fc99e Initial load
duke
parents:
diff changeset
7095 _skipBits = 2; // skip next two marked bits ("Printezis-marks")
a61af66fc99e Initial load
duke
parents:
diff changeset
7096 oop p = oop(addr);
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
7097 if (p->klass_or_null() == NULL || !p->is_parsable()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7098 DEBUG_ONLY(if (!_verifying) {)
a61af66fc99e Initial load
duke
parents:
diff changeset
7099 // We re-dirty the cards on which this object lies and increase
a61af66fc99e Initial load
duke
parents:
diff changeset
7100 // the _threshold so that we'll come back to scan this object
a61af66fc99e Initial load
duke
parents:
diff changeset
7101 // during the preclean or remark phase. (CMSCleanOnEnter)
a61af66fc99e Initial load
duke
parents:
diff changeset
7102 if (CMSCleanOnEnter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7103 size_t sz = _collector->block_size_using_printezis_bits(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7104 HeapWord* end_card_addr = (HeapWord*)round_to(
a61af66fc99e Initial load
duke
parents:
diff changeset
7105 (intptr_t)(addr+sz), CardTableModRefBS::card_size);
283
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7106 MemRegion redirty_range = MemRegion(addr, end_card_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7107 assert(!redirty_range.is_empty(), "Arithmetical tautology");
a61af66fc99e Initial load
duke
parents:
diff changeset
7108 // Bump _threshold to end_card_addr; note that
a61af66fc99e Initial load
duke
parents:
diff changeset
7109 // _threshold cannot possibly exceed end_card_addr, anyhow.
a61af66fc99e Initial load
duke
parents:
diff changeset
7110 // This prevents future clearing of the card as the scan proceeds
a61af66fc99e Initial load
duke
parents:
diff changeset
7111 // to the right.
a61af66fc99e Initial load
duke
parents:
diff changeset
7112 assert(_threshold <= end_card_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
7113 "Because we are just scanning into this object");
a61af66fc99e Initial load
duke
parents:
diff changeset
7114 if (_threshold < end_card_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7115 _threshold = end_card_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
7116 }
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
7117 if (p->klass_or_null() != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7118 // Redirty the range of cards...
a61af66fc99e Initial load
duke
parents:
diff changeset
7119 _mut->mark_range(redirty_range);
a61af66fc99e Initial load
duke
parents:
diff changeset
7120 } // ...else the setting of klass will dirty the card anyway.
a61af66fc99e Initial load
duke
parents:
diff changeset
7121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7122 DEBUG_ONLY(})
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7123 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7126 scanOopsInOop(addr);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7127 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7129
a61af66fc99e Initial load
duke
parents:
diff changeset
7130 // We take a break if we've been at this for a while,
a61af66fc99e Initial load
duke
parents:
diff changeset
7131 // so as to avoid monopolizing the locks involved.
a61af66fc99e Initial load
duke
parents:
diff changeset
7132 void MarkFromRootsClosure::do_yield_work() {
a61af66fc99e Initial load
duke
parents:
diff changeset
7133 // First give up the locks, then yield, then re-lock
a61af66fc99e Initial load
duke
parents:
diff changeset
7134 // We should probably use a constructor/destructor idiom to
a61af66fc99e Initial load
duke
parents:
diff changeset
7135 // do this unlock/lock or modify the MutexUnlocker class to
a61af66fc99e Initial load
duke
parents:
diff changeset
7136 // serve our purpose. XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
7137 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7138 "CMS thread should hold CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
7139 assert_lock_strong(_bitMap->lock());
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7140 DEBUG_ONLY(RememberKlassesChecker mux(false);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7141 _bitMap->lock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
7142 ConcurrentMarkSweepThread::desynchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
7143 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
7144 _collector->stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
7145 GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
a61af66fc99e Initial load
duke
parents:
diff changeset
7146 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7147 _collector->incrementYields();
a61af66fc99e Initial load
duke
parents:
diff changeset
7148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7149 _collector->icms_wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
7150
a61af66fc99e Initial load
duke
parents:
diff changeset
7151 // See the comment in coordinator_yield()
a61af66fc99e Initial load
duke
parents:
diff changeset
7152 for (unsigned i = 0; i < CMSYieldSleepCount &&
a61af66fc99e Initial load
duke
parents:
diff changeset
7153 ConcurrentMarkSweepThread::should_yield() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
7154 !CMSCollector::foregroundGCIsActive(); ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7155 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
7156 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
7157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7158
a61af66fc99e Initial load
duke
parents:
diff changeset
7159 ConcurrentMarkSweepThread::synchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
7160 _bitMap->lock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
7161 _collector->startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
7162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7163
a61af66fc99e Initial load
duke
parents:
diff changeset
7164 void MarkFromRootsClosure::scanOopsInOop(HeapWord* ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7165 assert(_bitMap->isMarked(ptr), "expected bit to be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
7166 assert(_markStack->isEmpty(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7167 "should drain stack to limit stack usage");
a61af66fc99e Initial load
duke
parents:
diff changeset
7168 // convert ptr to an oop preparatory to scanning
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7169 oop obj = oop(ptr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7170 // Ignore mark word in verification below, since we
a61af66fc99e Initial load
duke
parents:
diff changeset
7171 // may be running concurrent with mutators.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7172 assert(obj->is_oop(true), "should be an oop");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7173 assert(_finger <= ptr, "_finger runneth ahead");
a61af66fc99e Initial load
duke
parents:
diff changeset
7174 // advance the finger to right end of this object
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7175 _finger = ptr + obj->size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7176 assert(_finger > ptr, "we just incremented it above");
a61af66fc99e Initial load
duke
parents:
diff changeset
7177 // On large heaps, it may take us some time to get through
a61af66fc99e Initial load
duke
parents:
diff changeset
7178 // the marking phase (especially if running iCMS). During
a61af66fc99e Initial load
duke
parents:
diff changeset
7179 // this time it's possible that a lot of mutations have
a61af66fc99e Initial load
duke
parents:
diff changeset
7180 // accumulated in the card table and the mod union table --
a61af66fc99e Initial load
duke
parents:
diff changeset
7181 // these mutation records are redundant until we have
a61af66fc99e Initial load
duke
parents:
diff changeset
7182 // actually traced into the corresponding card.
a61af66fc99e Initial load
duke
parents:
diff changeset
7183 // Here, we check whether advancing the finger would make
a61af66fc99e Initial load
duke
parents:
diff changeset
7184 // us cross into a new card, and if so clear corresponding
a61af66fc99e Initial load
duke
parents:
diff changeset
7185 // cards in the MUT (preclean them in the card-table in the
a61af66fc99e Initial load
duke
parents:
diff changeset
7186 // future).
a61af66fc99e Initial load
duke
parents:
diff changeset
7187
a61af66fc99e Initial load
duke
parents:
diff changeset
7188 DEBUG_ONLY(if (!_verifying) {)
a61af66fc99e Initial load
duke
parents:
diff changeset
7189 // The clean-on-enter optimization is disabled by default,
a61af66fc99e Initial load
duke
parents:
diff changeset
7190 // until we fix 6178663.
a61af66fc99e Initial load
duke
parents:
diff changeset
7191 if (CMSCleanOnEnter && (_finger > _threshold)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7192 // [_threshold, _finger) represents the interval
a61af66fc99e Initial load
duke
parents:
diff changeset
7193 // of cards to be cleared in MUT (or precleaned in card table).
a61af66fc99e Initial load
duke
parents:
diff changeset
7194 // The set of cards to be cleared is all those that overlap
a61af66fc99e Initial load
duke
parents:
diff changeset
7195 // with the interval [_threshold, _finger); note that
a61af66fc99e Initial load
duke
parents:
diff changeset
7196 // _threshold is always kept card-aligned but _finger isn't
a61af66fc99e Initial load
duke
parents:
diff changeset
7197 // always card-aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
7198 HeapWord* old_threshold = _threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
7199 assert(old_threshold == (HeapWord*)round_to(
a61af66fc99e Initial load
duke
parents:
diff changeset
7200 (intptr_t)old_threshold, CardTableModRefBS::card_size),
a61af66fc99e Initial load
duke
parents:
diff changeset
7201 "_threshold should always be card-aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
7202 _threshold = (HeapWord*)round_to(
a61af66fc99e Initial load
duke
parents:
diff changeset
7203 (intptr_t)_finger, CardTableModRefBS::card_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
7204 MemRegion mr(old_threshold, _threshold);
a61af66fc99e Initial load
duke
parents:
diff changeset
7205 assert(!mr.is_empty(), "Control point invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
7206 assert(_span.contains(mr), "Should clear within span");
a61af66fc99e Initial load
duke
parents:
diff changeset
7207 // XXX When _finger crosses from old gen into perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
7208 // we may be doing unnecessary cleaning; do better in the
a61af66fc99e Initial load
duke
parents:
diff changeset
7209 // future by detecting that condition and clearing fewer
a61af66fc99e Initial load
duke
parents:
diff changeset
7210 // MUT/CT entries.
a61af66fc99e Initial load
duke
parents:
diff changeset
7211 _mut->clear_range(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7213 DEBUG_ONLY(})
a61af66fc99e Initial load
duke
parents:
diff changeset
7214 // Note: the finger doesn't advance while we drain
a61af66fc99e Initial load
duke
parents:
diff changeset
7215 // the stack below.
a61af66fc99e Initial load
duke
parents:
diff changeset
7216 PushOrMarkClosure pushOrMarkClosure(_collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
7217 _span, _bitMap, _markStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7218 _revisitStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7219 _finger, this);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7220 bool res = _markStack->push(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7221 assert(res, "Empty non-zero size stack should have space for single push");
a61af66fc99e Initial load
duke
parents:
diff changeset
7222 while (!_markStack->isEmpty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7223 oop new_oop = _markStack->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
7224 // Skip verifying header mark word below because we are
a61af66fc99e Initial load
duke
parents:
diff changeset
7225 // running concurrent with mutators.
a61af66fc99e Initial load
duke
parents:
diff changeset
7226 assert(new_oop->is_oop(true), "Oops! expected to pop an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
7227 // now scan this oop's oops
a61af66fc99e Initial load
duke
parents:
diff changeset
7228 new_oop->oop_iterate(&pushOrMarkClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
7229 do_yield_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
7230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7231 assert(_markStack->isEmpty(), "tautology, emphasizing post-condition");
a61af66fc99e Initial load
duke
parents:
diff changeset
7232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7233
a61af66fc99e Initial load
duke
parents:
diff changeset
7234 Par_MarkFromRootsClosure::Par_MarkFromRootsClosure(CMSConcMarkingTask* task,
a61af66fc99e Initial load
duke
parents:
diff changeset
7235 CMSCollector* collector, MemRegion span,
a61af66fc99e Initial load
duke
parents:
diff changeset
7236 CMSBitMap* bit_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
7237 OopTaskQueue* work_queue,
a61af66fc99e Initial load
duke
parents:
diff changeset
7238 CMSMarkStack* overflow_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7239 CMSMarkStack* revisit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7240 bool should_yield):
a61af66fc99e Initial load
duke
parents:
diff changeset
7241 _collector(collector),
a61af66fc99e Initial load
duke
parents:
diff changeset
7242 _whole_span(collector->_span),
a61af66fc99e Initial load
duke
parents:
diff changeset
7243 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
7244 _bit_map(bit_map),
a61af66fc99e Initial load
duke
parents:
diff changeset
7245 _mut(&collector->_modUnionTable),
a61af66fc99e Initial load
duke
parents:
diff changeset
7246 _work_queue(work_queue),
a61af66fc99e Initial load
duke
parents:
diff changeset
7247 _overflow_stack(overflow_stack),
a61af66fc99e Initial load
duke
parents:
diff changeset
7248 _revisit_stack(revisit_stack),
a61af66fc99e Initial load
duke
parents:
diff changeset
7249 _yield(should_yield),
a61af66fc99e Initial load
duke
parents:
diff changeset
7250 _skip_bits(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
7251 _task(task)
a61af66fc99e Initial load
duke
parents:
diff changeset
7252 {
a61af66fc99e Initial load
duke
parents:
diff changeset
7253 assert(_work_queue->size() == 0, "work_queue should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
7254 _finger = span.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
7255 _threshold = _finger; // XXX Defer clear-on-enter optimization for now
a61af66fc99e Initial load
duke
parents:
diff changeset
7256 assert(_span.contains(_finger), "Out of bounds _finger?");
a61af66fc99e Initial load
duke
parents:
diff changeset
7257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7258
a61af66fc99e Initial load
duke
parents:
diff changeset
7259 // Should revisit to see if this should be restructured for
a61af66fc99e Initial load
duke
parents:
diff changeset
7260 // greater efficiency.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7261 bool Par_MarkFromRootsClosure::do_bit(size_t offset) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7262 if (_skip_bits > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7263 _skip_bits--;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7264 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7266 // convert offset into a HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
7267 HeapWord* addr = _bit_map->startWord() + offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
7268 assert(_bit_map->endWord() && addr < _bit_map->endWord(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7269 "address out of range");
a61af66fc99e Initial load
duke
parents:
diff changeset
7270 assert(_bit_map->isMarked(addr), "tautology");
a61af66fc99e Initial load
duke
parents:
diff changeset
7271 if (_bit_map->isMarked(addr+1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7272 // this is an allocated object that might not yet be initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
7273 assert(_skip_bits == 0, "tautology");
a61af66fc99e Initial load
duke
parents:
diff changeset
7274 _skip_bits = 2; // skip next two marked bits ("Printezis-marks")
a61af66fc99e Initial load
duke
parents:
diff changeset
7275 oop p = oop(addr);
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
7276 if (p->klass_or_null() == NULL || !p->is_parsable()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7277 // in the case of Clean-on-Enter optimization, redirty card
a61af66fc99e Initial load
duke
parents:
diff changeset
7278 // and avoid clearing card by increasing the threshold.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7279 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7282 scan_oops_in_oop(addr);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7283 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7285
a61af66fc99e Initial load
duke
parents:
diff changeset
7286 void Par_MarkFromRootsClosure::scan_oops_in_oop(HeapWord* ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7287 assert(_bit_map->isMarked(ptr), "expected bit to be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
7288 // Should we assert that our work queue is empty or
a61af66fc99e Initial load
duke
parents:
diff changeset
7289 // below some drain limit?
a61af66fc99e Initial load
duke
parents:
diff changeset
7290 assert(_work_queue->size() == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
7291 "should drain stack to limit stack usage");
a61af66fc99e Initial load
duke
parents:
diff changeset
7292 // convert ptr to an oop preparatory to scanning
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7293 oop obj = oop(ptr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7294 // Ignore mark word in verification below, since we
a61af66fc99e Initial load
duke
parents:
diff changeset
7295 // may be running concurrent with mutators.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7296 assert(obj->is_oop(true), "should be an oop");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7297 assert(_finger <= ptr, "_finger runneth ahead");
a61af66fc99e Initial load
duke
parents:
diff changeset
7298 // advance the finger to right end of this object
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7299 _finger = ptr + obj->size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7300 assert(_finger > ptr, "we just incremented it above");
a61af66fc99e Initial load
duke
parents:
diff changeset
7301 // On large heaps, it may take us some time to get through
a61af66fc99e Initial load
duke
parents:
diff changeset
7302 // the marking phase (especially if running iCMS). During
a61af66fc99e Initial load
duke
parents:
diff changeset
7303 // this time it's possible that a lot of mutations have
a61af66fc99e Initial load
duke
parents:
diff changeset
7304 // accumulated in the card table and the mod union table --
a61af66fc99e Initial load
duke
parents:
diff changeset
7305 // these mutation records are redundant until we have
a61af66fc99e Initial load
duke
parents:
diff changeset
7306 // actually traced into the corresponding card.
a61af66fc99e Initial load
duke
parents:
diff changeset
7307 // Here, we check whether advancing the finger would make
a61af66fc99e Initial load
duke
parents:
diff changeset
7308 // us cross into a new card, and if so clear corresponding
a61af66fc99e Initial load
duke
parents:
diff changeset
7309 // cards in the MUT (preclean them in the card-table in the
a61af66fc99e Initial load
duke
parents:
diff changeset
7310 // future).
a61af66fc99e Initial load
duke
parents:
diff changeset
7311
a61af66fc99e Initial load
duke
parents:
diff changeset
7312 // The clean-on-enter optimization is disabled by default,
a61af66fc99e Initial load
duke
parents:
diff changeset
7313 // until we fix 6178663.
a61af66fc99e Initial load
duke
parents:
diff changeset
7314 if (CMSCleanOnEnter && (_finger > _threshold)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7315 // [_threshold, _finger) represents the interval
a61af66fc99e Initial load
duke
parents:
diff changeset
7316 // of cards to be cleared in MUT (or precleaned in card table).
a61af66fc99e Initial load
duke
parents:
diff changeset
7317 // The set of cards to be cleared is all those that overlap
a61af66fc99e Initial load
duke
parents:
diff changeset
7318 // with the interval [_threshold, _finger); note that
a61af66fc99e Initial load
duke
parents:
diff changeset
7319 // _threshold is always kept card-aligned but _finger isn't
a61af66fc99e Initial load
duke
parents:
diff changeset
7320 // always card-aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
7321 HeapWord* old_threshold = _threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
7322 assert(old_threshold == (HeapWord*)round_to(
a61af66fc99e Initial load
duke
parents:
diff changeset
7323 (intptr_t)old_threshold, CardTableModRefBS::card_size),
a61af66fc99e Initial load
duke
parents:
diff changeset
7324 "_threshold should always be card-aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
7325 _threshold = (HeapWord*)round_to(
a61af66fc99e Initial load
duke
parents:
diff changeset
7326 (intptr_t)_finger, CardTableModRefBS::card_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
7327 MemRegion mr(old_threshold, _threshold);
a61af66fc99e Initial load
duke
parents:
diff changeset
7328 assert(!mr.is_empty(), "Control point invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
7329 assert(_span.contains(mr), "Should clear within span"); // _whole_span ??
a61af66fc99e Initial load
duke
parents:
diff changeset
7330 // XXX When _finger crosses from old gen into perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
7331 // we may be doing unnecessary cleaning; do better in the
a61af66fc99e Initial load
duke
parents:
diff changeset
7332 // future by detecting that condition and clearing fewer
a61af66fc99e Initial load
duke
parents:
diff changeset
7333 // MUT/CT entries.
a61af66fc99e Initial load
duke
parents:
diff changeset
7334 _mut->clear_range(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7336
a61af66fc99e Initial load
duke
parents:
diff changeset
7337 // Note: the local finger doesn't advance while we drain
a61af66fc99e Initial load
duke
parents:
diff changeset
7338 // the stack below, but the global finger sure can and will.
a61af66fc99e Initial load
duke
parents:
diff changeset
7339 HeapWord** gfa = _task->global_finger_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
7340 Par_PushOrMarkClosure pushOrMarkClosure(_collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
7341 _span, _bit_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
7342 _work_queue,
a61af66fc99e Initial load
duke
parents:
diff changeset
7343 _overflow_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7344 _revisit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7345 _finger,
a61af66fc99e Initial load
duke
parents:
diff changeset
7346 gfa, this);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7347 bool res = _work_queue->push(obj); // overflow could occur here
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7348 assert(res, "Will hold once we use workqueues");
a61af66fc99e Initial load
duke
parents:
diff changeset
7349 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7350 oop new_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
7351 if (!_work_queue->pop_local(new_oop)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7352 // We emptied our work_queue; check if there's stuff that can
a61af66fc99e Initial load
duke
parents:
diff changeset
7353 // be gotten from the overflow stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
7354 if (CMSConcMarkingTask::get_work_from_overflow_stack(
a61af66fc99e Initial load
duke
parents:
diff changeset
7355 _overflow_stack, _work_queue)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7356 do_yield_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
7357 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
7358 } else { // done
a61af66fc99e Initial load
duke
parents:
diff changeset
7359 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
7360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7362 // Skip verifying header mark word below because we are
a61af66fc99e Initial load
duke
parents:
diff changeset
7363 // running concurrent with mutators.
a61af66fc99e Initial load
duke
parents:
diff changeset
7364 assert(new_oop->is_oop(true), "Oops! expected to pop an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
7365 // now scan this oop's oops
a61af66fc99e Initial load
duke
parents:
diff changeset
7366 new_oop->oop_iterate(&pushOrMarkClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
7367 do_yield_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
7368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7369 assert(_work_queue->size() == 0, "tautology, emphasizing post-condition");
a61af66fc99e Initial load
duke
parents:
diff changeset
7370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7371
a61af66fc99e Initial load
duke
parents:
diff changeset
7372 // Yield in response to a request from VM Thread or
a61af66fc99e Initial load
duke
parents:
diff changeset
7373 // from mutators.
a61af66fc99e Initial load
duke
parents:
diff changeset
7374 void Par_MarkFromRootsClosure::do_yield_work() {
a61af66fc99e Initial load
duke
parents:
diff changeset
7375 assert(_task != NULL, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
7376 _task->yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
7377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7378
a61af66fc99e Initial load
duke
parents:
diff changeset
7379 // A variant of the above used for verifying CMS marking work.
a61af66fc99e Initial load
duke
parents:
diff changeset
7380 MarkFromRootsVerifyClosure::MarkFromRootsVerifyClosure(CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
7381 MemRegion span,
a61af66fc99e Initial load
duke
parents:
diff changeset
7382 CMSBitMap* verification_bm, CMSBitMap* cms_bm,
a61af66fc99e Initial load
duke
parents:
diff changeset
7383 CMSMarkStack* mark_stack):
a61af66fc99e Initial load
duke
parents:
diff changeset
7384 _collector(collector),
a61af66fc99e Initial load
duke
parents:
diff changeset
7385 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
7386 _verification_bm(verification_bm),
a61af66fc99e Initial load
duke
parents:
diff changeset
7387 _cms_bm(cms_bm),
a61af66fc99e Initial load
duke
parents:
diff changeset
7388 _mark_stack(mark_stack),
a61af66fc99e Initial load
duke
parents:
diff changeset
7389 _pam_verify_closure(collector, span, verification_bm, cms_bm,
a61af66fc99e Initial load
duke
parents:
diff changeset
7390 mark_stack)
a61af66fc99e Initial load
duke
parents:
diff changeset
7391 {
a61af66fc99e Initial load
duke
parents:
diff changeset
7392 assert(_mark_stack->isEmpty(), "stack should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
7393 _finger = _verification_bm->startWord();
a61af66fc99e Initial load
duke
parents:
diff changeset
7394 assert(_collector->_restart_addr == NULL, "Sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
7395 assert(_span.contains(_finger), "Out of bounds _finger?");
a61af66fc99e Initial load
duke
parents:
diff changeset
7396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7397
a61af66fc99e Initial load
duke
parents:
diff changeset
7398 void MarkFromRootsVerifyClosure::reset(HeapWord* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7399 assert(_mark_stack->isEmpty(), "would cause duplicates on stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
7400 assert(_span.contains(addr), "Out of bounds _finger?");
a61af66fc99e Initial load
duke
parents:
diff changeset
7401 _finger = addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
7402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7403
a61af66fc99e Initial load
duke
parents:
diff changeset
7404 // Should revisit to see if this should be restructured for
a61af66fc99e Initial load
duke
parents:
diff changeset
7405 // greater efficiency.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7406 bool MarkFromRootsVerifyClosure::do_bit(size_t offset) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7407 // convert offset into a HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
7408 HeapWord* addr = _verification_bm->startWord() + offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
7409 assert(_verification_bm->endWord() && addr < _verification_bm->endWord(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7410 "address out of range");
a61af66fc99e Initial load
duke
parents:
diff changeset
7411 assert(_verification_bm->isMarked(addr), "tautology");
a61af66fc99e Initial load
duke
parents:
diff changeset
7412 assert(_cms_bm->isMarked(addr), "tautology");
a61af66fc99e Initial load
duke
parents:
diff changeset
7413
a61af66fc99e Initial load
duke
parents:
diff changeset
7414 assert(_mark_stack->isEmpty(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7415 "should drain stack to limit stack usage");
a61af66fc99e Initial load
duke
parents:
diff changeset
7416 // convert addr to an oop preparatory to scanning
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7417 oop obj = oop(addr);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7418 assert(obj->is_oop(), "should be an oop");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7419 assert(_finger <= addr, "_finger runneth ahead");
a61af66fc99e Initial load
duke
parents:
diff changeset
7420 // advance the finger to right end of this object
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7421 _finger = addr + obj->size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7422 assert(_finger > addr, "we just incremented it above");
a61af66fc99e Initial load
duke
parents:
diff changeset
7423 // Note: the finger doesn't advance while we drain
a61af66fc99e Initial load
duke
parents:
diff changeset
7424 // the stack below.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7425 bool res = _mark_stack->push(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7426 assert(res, "Empty non-zero size stack should have space for single push");
a61af66fc99e Initial load
duke
parents:
diff changeset
7427 while (!_mark_stack->isEmpty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7428 oop new_oop = _mark_stack->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
7429 assert(new_oop->is_oop(), "Oops! expected to pop an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
7430 // now scan this oop's oops
a61af66fc99e Initial load
duke
parents:
diff changeset
7431 new_oop->oop_iterate(&_pam_verify_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
7432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7433 assert(_mark_stack->isEmpty(), "tautology, emphasizing post-condition");
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7434 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7436
a61af66fc99e Initial load
duke
parents:
diff changeset
7437 PushAndMarkVerifyClosure::PushAndMarkVerifyClosure(
a61af66fc99e Initial load
duke
parents:
diff changeset
7438 CMSCollector* collector, MemRegion span,
a61af66fc99e Initial load
duke
parents:
diff changeset
7439 CMSBitMap* verification_bm, CMSBitMap* cms_bm,
a61af66fc99e Initial load
duke
parents:
diff changeset
7440 CMSMarkStack* mark_stack):
a61af66fc99e Initial load
duke
parents:
diff changeset
7441 OopClosure(collector->ref_processor()),
a61af66fc99e Initial load
duke
parents:
diff changeset
7442 _collector(collector),
a61af66fc99e Initial load
duke
parents:
diff changeset
7443 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
7444 _verification_bm(verification_bm),
a61af66fc99e Initial load
duke
parents:
diff changeset
7445 _cms_bm(cms_bm),
a61af66fc99e Initial load
duke
parents:
diff changeset
7446 _mark_stack(mark_stack)
a61af66fc99e Initial load
duke
parents:
diff changeset
7447 { }
a61af66fc99e Initial load
duke
parents:
diff changeset
7448
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7449 void PushAndMarkVerifyClosure::do_oop(oop* p) { PushAndMarkVerifyClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7450 void PushAndMarkVerifyClosure::do_oop(narrowOop* p) { PushAndMarkVerifyClosure::do_oop_work(p); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7451
a61af66fc99e Initial load
duke
parents:
diff changeset
7452 // Upon stack overflow, we discard (part of) the stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7453 // remembering the least address amongst those discarded
a61af66fc99e Initial load
duke
parents:
diff changeset
7454 // in CMSCollector's _restart_address.
a61af66fc99e Initial load
duke
parents:
diff changeset
7455 void PushAndMarkVerifyClosure::handle_stack_overflow(HeapWord* lost) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7456 // Remember the least grey address discarded
a61af66fc99e Initial load
duke
parents:
diff changeset
7457 HeapWord* ra = (HeapWord*)_mark_stack->least_value(lost);
a61af66fc99e Initial load
duke
parents:
diff changeset
7458 _collector->lower_restart_addr(ra);
a61af66fc99e Initial load
duke
parents:
diff changeset
7459 _mark_stack->reset(); // discard stack contents
a61af66fc99e Initial load
duke
parents:
diff changeset
7460 _mark_stack->expand(); // expand the stack if possible
a61af66fc99e Initial load
duke
parents:
diff changeset
7461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7462
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7463 void PushAndMarkVerifyClosure::do_oop(oop obj) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7464 assert(obj->is_oop_or_null(), "expected an oop or NULL");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7465 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7466 if (_span.contains(addr) && !_verification_bm->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7467 // Oop lies in _span and isn't yet grey or black
a61af66fc99e Initial load
duke
parents:
diff changeset
7468 _verification_bm->mark(addr); // now grey
a61af66fc99e Initial load
duke
parents:
diff changeset
7469 if (!_cms_bm->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7470 oop(addr)->print();
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7471 gclog_or_tty->print_cr(" (" INTPTR_FORMAT " should have been marked)",
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7472 addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7473 fatal("... aborting");
a61af66fc99e Initial load
duke
parents:
diff changeset
7474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7475
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7476 if (!_mark_stack->push(obj)) { // stack overflow
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7477 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7478 gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
a61af66fc99e Initial load
duke
parents:
diff changeset
7479 SIZE_FORMAT, _mark_stack->capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
7480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7481 assert(_mark_stack->isFull(), "Else push should have succeeded");
a61af66fc99e Initial load
duke
parents:
diff changeset
7482 handle_stack_overflow(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7484 // anything including and to the right of _finger
a61af66fc99e Initial load
duke
parents:
diff changeset
7485 // will be scanned as we iterate over the remainder of the
a61af66fc99e Initial load
duke
parents:
diff changeset
7486 // bit map
a61af66fc99e Initial load
duke
parents:
diff changeset
7487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7489
a61af66fc99e Initial load
duke
parents:
diff changeset
7490 PushOrMarkClosure::PushOrMarkClosure(CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
7491 MemRegion span,
a61af66fc99e Initial load
duke
parents:
diff changeset
7492 CMSBitMap* bitMap, CMSMarkStack* markStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7493 CMSMarkStack* revisitStack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7494 HeapWord* finger, MarkFromRootsClosure* parent) :
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7495 KlassRememberingOopClosure(collector, collector->ref_processor(), revisitStack),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7496 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
7497 _bitMap(bitMap),
a61af66fc99e Initial load
duke
parents:
diff changeset
7498 _markStack(markStack),
a61af66fc99e Initial load
duke
parents:
diff changeset
7499 _finger(finger),
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7500 _parent(parent)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7501 { }
a61af66fc99e Initial load
duke
parents:
diff changeset
7502
a61af66fc99e Initial load
duke
parents:
diff changeset
7503 Par_PushOrMarkClosure::Par_PushOrMarkClosure(CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
7504 MemRegion span,
a61af66fc99e Initial load
duke
parents:
diff changeset
7505 CMSBitMap* bit_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
7506 OopTaskQueue* work_queue,
a61af66fc99e Initial load
duke
parents:
diff changeset
7507 CMSMarkStack* overflow_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7508 CMSMarkStack* revisit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7509 HeapWord* finger,
a61af66fc99e Initial load
duke
parents:
diff changeset
7510 HeapWord** global_finger_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
7511 Par_MarkFromRootsClosure* parent) :
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7512 Par_KlassRememberingOopClosure(collector,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7513 collector->ref_processor(),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7514 revisit_stack),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7515 _whole_span(collector->_span),
a61af66fc99e Initial load
duke
parents:
diff changeset
7516 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
7517 _bit_map(bit_map),
a61af66fc99e Initial load
duke
parents:
diff changeset
7518 _work_queue(work_queue),
a61af66fc99e Initial load
duke
parents:
diff changeset
7519 _overflow_stack(overflow_stack),
a61af66fc99e Initial load
duke
parents:
diff changeset
7520 _finger(finger),
a61af66fc99e Initial load
duke
parents:
diff changeset
7521 _global_finger_addr(global_finger_addr),
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7522 _parent(parent)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7523 { }
a61af66fc99e Initial load
duke
parents:
diff changeset
7524
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
7525 // Assumes thread-safe access by callers, who are
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
7526 // responsible for mutual exclusion.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7527 void CMSCollector::lower_restart_addr(HeapWord* low) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7528 assert(_span.contains(low), "Out of bounds addr");
a61af66fc99e Initial load
duke
parents:
diff changeset
7529 if (_restart_addr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7530 _restart_addr = low;
a61af66fc99e Initial load
duke
parents:
diff changeset
7531 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
7532 _restart_addr = MIN2(_restart_addr, low);
a61af66fc99e Initial load
duke
parents:
diff changeset
7533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7535
a61af66fc99e Initial load
duke
parents:
diff changeset
7536 // Upon stack overflow, we discard (part of) the stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7537 // remembering the least address amongst those discarded
a61af66fc99e Initial load
duke
parents:
diff changeset
7538 // in CMSCollector's _restart_address.
a61af66fc99e Initial load
duke
parents:
diff changeset
7539 void PushOrMarkClosure::handle_stack_overflow(HeapWord* lost) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7540 // Remember the least grey address discarded
a61af66fc99e Initial load
duke
parents:
diff changeset
7541 HeapWord* ra = (HeapWord*)_markStack->least_value(lost);
a61af66fc99e Initial load
duke
parents:
diff changeset
7542 _collector->lower_restart_addr(ra);
a61af66fc99e Initial load
duke
parents:
diff changeset
7543 _markStack->reset(); // discard stack contents
a61af66fc99e Initial load
duke
parents:
diff changeset
7544 _markStack->expand(); // expand the stack if possible
a61af66fc99e Initial load
duke
parents:
diff changeset
7545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7546
a61af66fc99e Initial load
duke
parents:
diff changeset
7547 // Upon stack overflow, we discard (part of) the stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7548 // remembering the least address amongst those discarded
a61af66fc99e Initial load
duke
parents:
diff changeset
7549 // in CMSCollector's _restart_address.
a61af66fc99e Initial load
duke
parents:
diff changeset
7550 void Par_PushOrMarkClosure::handle_stack_overflow(HeapWord* lost) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7551 // We need to do this under a mutex to prevent other
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 283
diff changeset
7552 // workers from interfering with the work done below.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7553 MutexLockerEx ml(_overflow_stack->par_lock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7554 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
7555 // Remember the least grey address discarded
a61af66fc99e Initial load
duke
parents:
diff changeset
7556 HeapWord* ra = (HeapWord*)_overflow_stack->least_value(lost);
a61af66fc99e Initial load
duke
parents:
diff changeset
7557 _collector->lower_restart_addr(ra);
a61af66fc99e Initial load
duke
parents:
diff changeset
7558 _overflow_stack->reset(); // discard stack contents
a61af66fc99e Initial load
duke
parents:
diff changeset
7559 _overflow_stack->expand(); // expand the stack if possible
a61af66fc99e Initial load
duke
parents:
diff changeset
7560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7561
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7562 void PushOrMarkClosure::do_oop(oop obj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7563 // Ignore mark word because we are running concurrent with mutators.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7564 assert(obj->is_oop_or_null(true), "expected an oop or NULL");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7565 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7566 if (_span.contains(addr) && !_bitMap->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7567 // Oop lies in _span and isn't yet grey or black
a61af66fc99e Initial load
duke
parents:
diff changeset
7568 _bitMap->mark(addr); // now grey
a61af66fc99e Initial load
duke
parents:
diff changeset
7569 if (addr < _finger) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7570 // the bit map iteration has already either passed, or
a61af66fc99e Initial load
duke
parents:
diff changeset
7571 // sampled, this bit in the bit map; we'll need to
a61af66fc99e Initial load
duke
parents:
diff changeset
7572 // use the marking stack to scan this oop's oops.
a61af66fc99e Initial load
duke
parents:
diff changeset
7573 bool simulate_overflow = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
7574 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
7575 if (CMSMarkStackOverflowALot &&
a61af66fc99e Initial load
duke
parents:
diff changeset
7576 _collector->simulate_overflow()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7577 // simulate a stack overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
7578 simulate_overflow = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
7579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7580 )
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7581 if (simulate_overflow || !_markStack->push(obj)) { // stack overflow
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7582 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7583 gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
a61af66fc99e Initial load
duke
parents:
diff changeset
7584 SIZE_FORMAT, _markStack->capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
7585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7586 assert(simulate_overflow || _markStack->isFull(), "Else push should have succeeded");
a61af66fc99e Initial load
duke
parents:
diff changeset
7587 handle_stack_overflow(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7590 // anything including and to the right of _finger
a61af66fc99e Initial load
duke
parents:
diff changeset
7591 // will be scanned as we iterate over the remainder of the
a61af66fc99e Initial load
duke
parents:
diff changeset
7592 // bit map
a61af66fc99e Initial load
duke
parents:
diff changeset
7593 do_yield_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
7594 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7596
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7597 void PushOrMarkClosure::do_oop(oop* p) { PushOrMarkClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7598 void PushOrMarkClosure::do_oop(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7599
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7600 void Par_PushOrMarkClosure::do_oop(oop obj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7601 // Ignore mark word because we are running concurrent with mutators.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7602 assert(obj->is_oop_or_null(true), "expected an oop or NULL");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7603 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7604 if (_whole_span.contains(addr) && !_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7605 // Oop lies in _span and isn't yet grey or black
a61af66fc99e Initial load
duke
parents:
diff changeset
7606 // We read the global_finger (volatile read) strictly after marking oop
a61af66fc99e Initial load
duke
parents:
diff changeset
7607 bool res = _bit_map->par_mark(addr); // now grey
a61af66fc99e Initial load
duke
parents:
diff changeset
7608 volatile HeapWord** gfa = (volatile HeapWord**)_global_finger_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
7609 // Should we push this marked oop on our stack?
a61af66fc99e Initial load
duke
parents:
diff changeset
7610 // -- if someone else marked it, nothing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
7611 // -- if target oop is above global finger nothing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
7612 // -- if target oop is in chunk and above local finger
a61af66fc99e Initial load
duke
parents:
diff changeset
7613 // then nothing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
7614 // -- else push on work queue
a61af66fc99e Initial load
duke
parents:
diff changeset
7615 if ( !res // someone else marked it, they will deal with it
a61af66fc99e Initial load
duke
parents:
diff changeset
7616 || (addr >= *gfa) // will be scanned in a later task
a61af66fc99e Initial load
duke
parents:
diff changeset
7617 || (_span.contains(addr) && addr >= _finger)) { // later in this chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
7618 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
7619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7620 // the bit map iteration has already either passed, or
a61af66fc99e Initial load
duke
parents:
diff changeset
7621 // sampled, this bit in the bit map; we'll need to
a61af66fc99e Initial load
duke
parents:
diff changeset
7622 // use the marking stack to scan this oop's oops.
a61af66fc99e Initial load
duke
parents:
diff changeset
7623 bool simulate_overflow = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
7624 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
7625 if (CMSMarkStackOverflowALot &&
a61af66fc99e Initial load
duke
parents:
diff changeset
7626 _collector->simulate_overflow()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7627 // simulate a stack overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
7628 simulate_overflow = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
7629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7630 )
a61af66fc99e Initial load
duke
parents:
diff changeset
7631 if (simulate_overflow ||
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7632 !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7633 // stack overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
7634 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7635 gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
a61af66fc99e Initial load
duke
parents:
diff changeset
7636 SIZE_FORMAT, _overflow_stack->capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
7637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7638 // We cannot assert that the overflow stack is full because
a61af66fc99e Initial load
duke
parents:
diff changeset
7639 // it may have been emptied since.
a61af66fc99e Initial load
duke
parents:
diff changeset
7640 assert(simulate_overflow ||
a61af66fc99e Initial load
duke
parents:
diff changeset
7641 _work_queue->size() == _work_queue->max_elems(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7642 "Else push should have succeeded");
a61af66fc99e Initial load
duke
parents:
diff changeset
7643 handle_stack_overflow(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
7644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7645 do_yield_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
7646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7648
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7649 void Par_PushOrMarkClosure::do_oop(oop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7650 void Par_PushOrMarkClosure::do_oop(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7651
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7652 KlassRememberingOopClosure::KlassRememberingOopClosure(CMSCollector* collector,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7653 ReferenceProcessor* rp,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7654 CMSMarkStack* revisit_stack) :
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7655 OopClosure(rp),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7656 _collector(collector),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7657 _revisit_stack(revisit_stack),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7658 _should_remember_klasses(collector->should_unload_classes()) {}
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7659
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7660 PushAndMarkClosure::PushAndMarkClosure(CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
7661 MemRegion span,
a61af66fc99e Initial load
duke
parents:
diff changeset
7662 ReferenceProcessor* rp,
a61af66fc99e Initial load
duke
parents:
diff changeset
7663 CMSBitMap* bit_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
7664 CMSBitMap* mod_union_table,
a61af66fc99e Initial load
duke
parents:
diff changeset
7665 CMSMarkStack* mark_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7666 CMSMarkStack* revisit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
7667 bool concurrent_precleaning):
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7668 KlassRememberingOopClosure(collector, rp, revisit_stack),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7669 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
7670 _bit_map(bit_map),
a61af66fc99e Initial load
duke
parents:
diff changeset
7671 _mod_union_table(mod_union_table),
a61af66fc99e Initial load
duke
parents:
diff changeset
7672 _mark_stack(mark_stack),
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7673 _concurrent_precleaning(concurrent_precleaning)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7674 {
a61af66fc99e Initial load
duke
parents:
diff changeset
7675 assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
7676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7677
a61af66fc99e Initial load
duke
parents:
diff changeset
7678 // Grey object rescan during pre-cleaning and second checkpoint phases --
a61af66fc99e Initial load
duke
parents:
diff changeset
7679 // the non-parallel version (the parallel version appears further below.)
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7680 void PushAndMarkClosure::do_oop(oop obj) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7681 // Ignore mark word verification. If during concurrent precleaning,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7682 // the object monitor may be locked. If during the checkpoint
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7683 // phases, the object may already have been reached by a different
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7684 // path and may be at the end of the global overflow list (so
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7685 // the mark word may be NULL).
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 143
diff changeset
7686 assert(obj->is_oop_or_null(true /* ignore mark word */),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7687 "expected an oop or NULL");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7688 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7689 // Check if oop points into the CMS generation
a61af66fc99e Initial load
duke
parents:
diff changeset
7690 // and is not marked
a61af66fc99e Initial load
duke
parents:
diff changeset
7691 if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7692 // a white object ...
a61af66fc99e Initial load
duke
parents:
diff changeset
7693 _bit_map->mark(addr); // ... now grey
a61af66fc99e Initial load
duke
parents:
diff changeset
7694 // push on the marking stack (grey set)
a61af66fc99e Initial load
duke
parents:
diff changeset
7695 bool simulate_overflow = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
7696 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
7697 if (CMSMarkStackOverflowALot &&
a61af66fc99e Initial load
duke
parents:
diff changeset
7698 _collector->simulate_overflow()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7699 // simulate a stack overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
7700 simulate_overflow = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
7701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7702 )
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7703 if (simulate_overflow || !_mark_stack->push(obj)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7704 if (_concurrent_precleaning) {
283
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7705 // During precleaning we can just dirty the appropriate card(s)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7706 // in the mod union table, thus ensuring that the object remains
283
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7707 // in the grey set and continue. In the case of object arrays
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7708 // we need to dirty all of the cards that the object spans,
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7709 // since the rescan of object arrays will be limited to the
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7710 // dirty cards.
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7711 // Note that no one can be intefering with us in this action
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7712 // of dirtying the mod union table, so no locking or atomics
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7713 // are required.
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7714 if (obj->is_objArray()) {
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7715 size_t sz = obj->size();
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7716 HeapWord* end_card_addr = (HeapWord*)round_to(
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7717 (intptr_t)(addr+sz), CardTableModRefBS::card_size);
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7718 MemRegion redirty_range = MemRegion(addr, end_card_addr);
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7719 assert(!redirty_range.is_empty(), "Arithmetical tautology");
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7720 _mod_union_table->mark_range(redirty_range);
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7721 } else {
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7722 _mod_union_table->mark(addr);
9199f248b0ee 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 271
diff changeset
7723 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7724 _collector->_ser_pmc_preclean_ovflw++;
a61af66fc99e Initial load
duke
parents:
diff changeset
7725 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
7726 // During the remark phase, we need to remember this oop
a61af66fc99e Initial load
duke
parents:
diff changeset
7727 // in the overflow list.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7728 _collector->push_on_overflow_list(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7729 _collector->_ser_pmc_remark_ovflw++;
a61af66fc99e Initial load
duke
parents:
diff changeset
7730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7734
a61af66fc99e Initial load
duke
parents:
diff changeset
7735 Par_PushAndMarkClosure::Par_PushAndMarkClosure(CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
7736 MemRegion span,
a61af66fc99e Initial load
duke
parents:
diff changeset
7737 ReferenceProcessor* rp,
a61af66fc99e Initial load
duke
parents:
diff changeset
7738 CMSBitMap* bit_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
7739 OopTaskQueue* work_queue,
a61af66fc99e Initial load
duke
parents:
diff changeset
7740 CMSMarkStack* revisit_stack):
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7741 Par_KlassRememberingOopClosure(collector, rp, revisit_stack),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7742 _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
7743 _bit_map(bit_map),
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7744 _work_queue(work_queue)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7745 {
a61af66fc99e Initial load
duke
parents:
diff changeset
7746 assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
7747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7748
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7749 void PushAndMarkClosure::do_oop(oop* p) { PushAndMarkClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7750 void PushAndMarkClosure::do_oop(narrowOop* p) { PushAndMarkClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7751
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7752 // Grey object rescan during second checkpoint phase --
a61af66fc99e Initial load
duke
parents:
diff changeset
7753 // the parallel version.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7754 void Par_PushAndMarkClosure::do_oop(oop obj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7755 // In the assert below, we ignore the mark word because
a61af66fc99e Initial load
duke
parents:
diff changeset
7756 // this oop may point to an already visited object that is
a61af66fc99e Initial load
duke
parents:
diff changeset
7757 // on the overflow stack (in which case the mark word has
a61af66fc99e Initial load
duke
parents:
diff changeset
7758 // been hijacked for chaining into the overflow stack --
a61af66fc99e Initial load
duke
parents:
diff changeset
7759 // if this is the last object in the overflow stack then
a61af66fc99e Initial load
duke
parents:
diff changeset
7760 // its mark word will be NULL). Because this object may
a61af66fc99e Initial load
duke
parents:
diff changeset
7761 // have been subsequently popped off the global overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
7762 // stack, and the mark word possibly restored to the prototypical
a61af66fc99e Initial load
duke
parents:
diff changeset
7763 // value, by the time we get to examined this failing assert in
a61af66fc99e Initial load
duke
parents:
diff changeset
7764 // the debugger, is_oop_or_null(false) may subsequently start
a61af66fc99e Initial load
duke
parents:
diff changeset
7765 // to hold.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7766 assert(obj->is_oop_or_null(true),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7767 "expected an oop or NULL");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7768 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7769 // Check if oop points into the CMS generation
a61af66fc99e Initial load
duke
parents:
diff changeset
7770 // and is not marked
a61af66fc99e Initial load
duke
parents:
diff changeset
7771 if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7772 // a white object ...
a61af66fc99e Initial load
duke
parents:
diff changeset
7773 // If we manage to "claim" the object, by being the
a61af66fc99e Initial load
duke
parents:
diff changeset
7774 // first thread to mark it, then we push it on our
a61af66fc99e Initial load
duke
parents:
diff changeset
7775 // marking stack
a61af66fc99e Initial load
duke
parents:
diff changeset
7776 if (_bit_map->par_mark(addr)) { // ... now grey
a61af66fc99e Initial load
duke
parents:
diff changeset
7777 // push on work queue (grey set)
a61af66fc99e Initial load
duke
parents:
diff changeset
7778 bool simulate_overflow = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
7779 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
7780 if (CMSMarkStackOverflowALot &&
a61af66fc99e Initial load
duke
parents:
diff changeset
7781 _collector->par_simulate_overflow()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7782 // simulate a stack overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
7783 simulate_overflow = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
7784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7785 )
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7786 if (simulate_overflow || !_work_queue->push(obj)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7787 _collector->par_push_on_overflow_list(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7788 _collector->_par_pmc_remark_ovflw++; // imprecise OK: no need to CAS
a61af66fc99e Initial load
duke
parents:
diff changeset
7789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7790 } // Else, some other thread got there first
a61af66fc99e Initial load
duke
parents:
diff changeset
7791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7793
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7794 void Par_PushAndMarkClosure::do_oop(oop* p) { Par_PushAndMarkClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7795 void Par_PushAndMarkClosure::do_oop(narrowOop* p) { Par_PushAndMarkClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
7796
941
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 935
diff changeset
7797 void PushAndMarkClosure::remember_mdo(DataLayout* v) {
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 935
diff changeset
7798 // TBD
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 935
diff changeset
7799 }
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 935
diff changeset
7800
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 935
diff changeset
7801 void Par_PushAndMarkClosure::remember_mdo(DataLayout* v) {
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 935
diff changeset
7802 // TBD
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 935
diff changeset
7803 }
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 935
diff changeset
7804
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7805 void CMSPrecleanRefsYieldClosure::do_yield_work() {
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
7806 DEBUG_ONLY(RememberKlassesChecker mux(false);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7807 Mutex* bml = _collector->bitMapLock();
a61af66fc99e Initial load
duke
parents:
diff changeset
7808 assert_lock_strong(bml);
a61af66fc99e Initial load
duke
parents:
diff changeset
7809 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7810 "CMS thread should hold CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
7811
a61af66fc99e Initial load
duke
parents:
diff changeset
7812 bml->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
7813 ConcurrentMarkSweepThread::desynchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
7814
a61af66fc99e Initial load
duke
parents:
diff changeset
7815 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
7816
a61af66fc99e Initial load
duke
parents:
diff changeset
7817 _collector->stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
7818 GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
a61af66fc99e Initial load
duke
parents:
diff changeset
7819 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7820 _collector->incrementYields();
a61af66fc99e Initial load
duke
parents:
diff changeset
7821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7822 _collector->icms_wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
7823
a61af66fc99e Initial load
duke
parents:
diff changeset
7824 // See the comment in coordinator_yield()
a61af66fc99e Initial load
duke
parents:
diff changeset
7825 for (unsigned i = 0; i < CMSYieldSleepCount &&
a61af66fc99e Initial load
duke
parents:
diff changeset
7826 ConcurrentMarkSweepThread::should_yield() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
7827 !CMSCollector::foregroundGCIsActive(); ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7828 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
7829 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
7830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7831
a61af66fc99e Initial load
duke
parents:
diff changeset
7832 ConcurrentMarkSweepThread::synchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
7833 bml->lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
7834
a61af66fc99e Initial load
duke
parents:
diff changeset
7835 _collector->startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
7836 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7837
a61af66fc99e Initial load
duke
parents:
diff changeset
7838 bool CMSPrecleanRefsYieldClosure::should_return() {
a61af66fc99e Initial load
duke
parents:
diff changeset
7839 if (ConcurrentMarkSweepThread::should_yield()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7840 do_yield_work();
a61af66fc99e Initial load
duke
parents:
diff changeset
7841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7842 return _collector->foregroundGCIsActive();
a61af66fc99e Initial load
duke
parents:
diff changeset
7843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7844
a61af66fc99e Initial load
duke
parents:
diff changeset
7845 void MarkFromDirtyCardsClosure::do_MemRegion(MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7846 assert(((size_t)mr.start())%CardTableModRefBS::card_size_in_words == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
7847 "mr should be aligned to start at a card boundary");
a61af66fc99e Initial load
duke
parents:
diff changeset
7848 // We'd like to assert:
a61af66fc99e Initial load
duke
parents:
diff changeset
7849 // assert(mr.word_size()%CardTableModRefBS::card_size_in_words == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
7850 // "mr should be a range of cards");
a61af66fc99e Initial load
duke
parents:
diff changeset
7851 // However, that would be too strong in one case -- the last
a61af66fc99e Initial load
duke
parents:
diff changeset
7852 // partition ends at _unallocated_block which, in general, can be
a61af66fc99e Initial load
duke
parents:
diff changeset
7853 // an arbitrary boundary, not necessarily card aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
7854 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7855 _num_dirty_cards +=
a61af66fc99e Initial load
duke
parents:
diff changeset
7856 mr.word_size()/CardTableModRefBS::card_size_in_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
7857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7858 _space->object_iterate_mem(mr, &_scan_cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
7859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7860
a61af66fc99e Initial load
duke
parents:
diff changeset
7861 SweepClosure::SweepClosure(CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
7862 ConcurrentMarkSweepGeneration* g,
a61af66fc99e Initial load
duke
parents:
diff changeset
7863 CMSBitMap* bitMap, bool should_yield) :
a61af66fc99e Initial load
duke
parents:
diff changeset
7864 _collector(collector),
a61af66fc99e Initial load
duke
parents:
diff changeset
7865 _g(g),
a61af66fc99e Initial load
duke
parents:
diff changeset
7866 _sp(g->cmsSpace()),
a61af66fc99e Initial load
duke
parents:
diff changeset
7867 _limit(_sp->sweep_limit()),
a61af66fc99e Initial load
duke
parents:
diff changeset
7868 _freelistLock(_sp->freelistLock()),
a61af66fc99e Initial load
duke
parents:
diff changeset
7869 _bitMap(bitMap),
a61af66fc99e Initial load
duke
parents:
diff changeset
7870 _yield(should_yield),
a61af66fc99e Initial load
duke
parents:
diff changeset
7871 _inFreeRange(false), // No free range at beginning of sweep
a61af66fc99e Initial load
duke
parents:
diff changeset
7872 _freeRangeInFreeLists(false), // No free range at beginning of sweep
a61af66fc99e Initial load
duke
parents:
diff changeset
7873 _lastFreeRangeCoalesced(false),
a61af66fc99e Initial load
duke
parents:
diff changeset
7874 _freeFinger(g->used_region().start())
a61af66fc99e Initial load
duke
parents:
diff changeset
7875 {
a61af66fc99e Initial load
duke
parents:
diff changeset
7876 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
7877 _numObjectsFreed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
7878 _numWordsFreed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
7879 _numObjectsLive = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
7880 _numWordsLive = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
7881 _numObjectsAlreadyFree = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
7882 _numWordsAlreadyFree = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
7883 _last_fc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
7884
a61af66fc99e Initial load
duke
parents:
diff changeset
7885 _sp->initializeIndexedFreeListArrayReturnedBytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
7886 _sp->dictionary()->initializeDictReturnedBytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
7887 )
a61af66fc99e Initial load
duke
parents:
diff changeset
7888 assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
7889 "sweep _limit out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
7890 if (CMSTraceSweeper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7891 gclog_or_tty->print("\n====================\nStarting new sweep\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
7892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7893 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7894
a61af66fc99e Initial load
duke
parents:
diff changeset
7895 // We need this destructor to reclaim any space at the end
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7896 // of the space, which do_blk below may not yet have added back to
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7897 // the free lists.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7898 SweepClosure::~SweepClosure() {
a61af66fc99e Initial load
duke
parents:
diff changeset
7899 assert_lock_strong(_freelistLock);
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7900 assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7901 "sweep _limit out of bounds");
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7902 // Flush any remaining coterminal free run as a single
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7903 // coalesced chunk to the appropriate free list.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7904 if (inFreeRange()) {
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7905 assert(freeFinger() < _limit, "freeFinger points too high");
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7906 flush_cur_free_chunk(freeFinger(), pointer_delta(_limit, freeFinger()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7907 if (CMSTraceSweeper) {
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7908 gclog_or_tty->print("Sweep: last chunk: ");
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7909 gclog_or_tty->print("put_free_blk 0x%x ("SIZE_FORMAT") [coalesced:"SIZE_FORMAT"]\n",
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7910 freeFinger(), pointer_delta(_limit, freeFinger()), lastFreeRangeCoalesced());
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7911 }
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7912 } // else nothing to flush
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7913 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
7914 if (Verbose && PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7915 gclog_or_tty->print("Collected "SIZE_FORMAT" objects, "
a61af66fc99e Initial load
duke
parents:
diff changeset
7916 SIZE_FORMAT " bytes",
a61af66fc99e Initial load
duke
parents:
diff changeset
7917 _numObjectsFreed, _numWordsFreed*sizeof(HeapWord));
a61af66fc99e Initial load
duke
parents:
diff changeset
7918 gclog_or_tty->print_cr("\nLive "SIZE_FORMAT" objects, "
a61af66fc99e Initial load
duke
parents:
diff changeset
7919 SIZE_FORMAT" bytes "
a61af66fc99e Initial load
duke
parents:
diff changeset
7920 "Already free "SIZE_FORMAT" objects, "SIZE_FORMAT" bytes",
a61af66fc99e Initial load
duke
parents:
diff changeset
7921 _numObjectsLive, _numWordsLive*sizeof(HeapWord),
a61af66fc99e Initial load
duke
parents:
diff changeset
7922 _numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord));
a61af66fc99e Initial load
duke
parents:
diff changeset
7923 size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree) *
a61af66fc99e Initial load
duke
parents:
diff changeset
7924 sizeof(HeapWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
7925 gclog_or_tty->print_cr("Total sweep: "SIZE_FORMAT" bytes", totalBytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
7926
a61af66fc99e Initial load
duke
parents:
diff changeset
7927 if (PrintCMSStatistics && CMSVerifyReturnedBytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7928 size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
7929 size_t dictReturnedBytes = _sp->dictionary()->sumDictReturnedBytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
7930 size_t returnedBytes = indexListReturnedBytes + dictReturnedBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
7931 gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returnedBytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
7932 gclog_or_tty->print(" Indexed List Returned "SIZE_FORMAT" bytes",
a61af66fc99e Initial load
duke
parents:
diff changeset
7933 indexListReturnedBytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
7934 gclog_or_tty->print_cr(" Dictionary Returned "SIZE_FORMAT" bytes",
a61af66fc99e Initial load
duke
parents:
diff changeset
7935 dictReturnedBytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
7936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7938 )
a61af66fc99e Initial load
duke
parents:
diff changeset
7939 // Now, in debug mode, just null out the sweep_limit
a61af66fc99e Initial load
duke
parents:
diff changeset
7940 NOT_PRODUCT(_sp->clear_sweep_limit();)
a61af66fc99e Initial load
duke
parents:
diff changeset
7941 if (CMSTraceSweeper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7942 gclog_or_tty->print("end of sweep\n================\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
7943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7945
a61af66fc99e Initial load
duke
parents:
diff changeset
7946 void SweepClosure::initialize_free_range(HeapWord* freeFinger,
a61af66fc99e Initial load
duke
parents:
diff changeset
7947 bool freeRangeInFreeLists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7948 if (CMSTraceSweeper) {
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7949 gclog_or_tty->print("---- Start free range at 0x%x with free block (%d)\n",
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
7950 freeFinger, freeRangeInFreeLists);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
7951 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7952 assert(!inFreeRange(), "Trampling existing free range");
a61af66fc99e Initial load
duke
parents:
diff changeset
7953 set_inFreeRange(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
7954 set_lastFreeRangeCoalesced(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
7955
a61af66fc99e Initial load
duke
parents:
diff changeset
7956 set_freeFinger(freeFinger);
a61af66fc99e Initial load
duke
parents:
diff changeset
7957 set_freeRangeInFreeLists(freeRangeInFreeLists);
a61af66fc99e Initial load
duke
parents:
diff changeset
7958 if (CMSTestInFreeList) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7959 if (freeRangeInFreeLists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7960 FreeChunk* fc = (FreeChunk*) freeFinger;
a61af66fc99e Initial load
duke
parents:
diff changeset
7961 assert(fc->isFree(), "A chunk on the free list should be free.");
a61af66fc99e Initial load
duke
parents:
diff changeset
7962 assert(fc->size() > 0, "Free range should have a size");
a61af66fc99e Initial load
duke
parents:
diff changeset
7963 assert(_sp->verifyChunkInFreeLists(fc), "Chunk is not in free lists");
a61af66fc99e Initial load
duke
parents:
diff changeset
7964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
7967
a61af66fc99e Initial load
duke
parents:
diff changeset
7968 // Note that the sweeper runs concurrently with mutators. Thus,
a61af66fc99e Initial load
duke
parents:
diff changeset
7969 // it is possible for direct allocation in this generation to happen
a61af66fc99e Initial load
duke
parents:
diff changeset
7970 // in the middle of the sweep. Note that the sweeper also coalesces
a61af66fc99e Initial load
duke
parents:
diff changeset
7971 // contiguous free blocks. Thus, unless the sweeper and the allocator
a61af66fc99e Initial load
duke
parents:
diff changeset
7972 // synchronize appropriately freshly allocated blocks may get swept up.
a61af66fc99e Initial load
duke
parents:
diff changeset
7973 // This is accomplished by the sweeper locking the free lists while
a61af66fc99e Initial load
duke
parents:
diff changeset
7974 // it is sweeping. Thus blocks that are determined to be free are
a61af66fc99e Initial load
duke
parents:
diff changeset
7975 // indeed free. There is however one additional complication:
a61af66fc99e Initial load
duke
parents:
diff changeset
7976 // blocks that have been allocated since the final checkpoint and
a61af66fc99e Initial load
duke
parents:
diff changeset
7977 // mark, will not have been marked and so would be treated as
a61af66fc99e Initial load
duke
parents:
diff changeset
7978 // unreachable and swept up. To prevent this, the allocator marks
a61af66fc99e Initial load
duke
parents:
diff changeset
7979 // the bit map when allocating during the sweep phase. This leads,
a61af66fc99e Initial load
duke
parents:
diff changeset
7980 // however, to a further complication -- objects may have been allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
7981 // but not yet initialized -- in the sense that the header isn't yet
a61af66fc99e Initial load
duke
parents:
diff changeset
7982 // installed. The sweeper can not then determine the size of the block
a61af66fc99e Initial load
duke
parents:
diff changeset
7983 // in order to skip over it. To deal with this case, we use a technique
a61af66fc99e Initial load
duke
parents:
diff changeset
7984 // (due to Printezis) to encode such uninitialized block sizes in the
a61af66fc99e Initial load
duke
parents:
diff changeset
7985 // bit map. Since the bit map uses a bit per every HeapWord, but the
a61af66fc99e Initial load
duke
parents:
diff changeset
7986 // CMS generation has a minimum object size of 3 HeapWords, it follows
a61af66fc99e Initial load
duke
parents:
diff changeset
7987 // that "normal marks" won't be adjacent in the bit map (there will
a61af66fc99e Initial load
duke
parents:
diff changeset
7988 // always be at least two 0 bits between successive 1 bits). We make use
a61af66fc99e Initial load
duke
parents:
diff changeset
7989 // of these "unused" bits to represent uninitialized blocks -- the bit
a61af66fc99e Initial load
duke
parents:
diff changeset
7990 // corresponding to the start of the uninitialized object and the next
a61af66fc99e Initial load
duke
parents:
diff changeset
7991 // bit are both set. Finally, a 1 bit marks the end of the object that
a61af66fc99e Initial load
duke
parents:
diff changeset
7992 // started with the two consecutive 1 bits to indicate its potentially
a61af66fc99e Initial load
duke
parents:
diff changeset
7993 // uninitialized state.
a61af66fc99e Initial load
duke
parents:
diff changeset
7994
a61af66fc99e Initial load
duke
parents:
diff changeset
7995 size_t SweepClosure::do_blk_careful(HeapWord* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
7996 FreeChunk* fc = (FreeChunk*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
7997 size_t res;
a61af66fc99e Initial load
duke
parents:
diff changeset
7998
1720
5ed703250bff 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 1716
diff changeset
7999 // Check if we are done sweeping. Below we check "addr >= _limit" rather
5ed703250bff 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 1716
diff changeset
8000 // than "addr == _limit" because although _limit was a block boundary when
5ed703250bff 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 1716
diff changeset
8001 // we started the sweep, it may no longer be one because heap expansion
5ed703250bff 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 1716
diff changeset
8002 // may have caused us to coalesce the block ending at the address _limit
5ed703250bff 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 1716
diff changeset
8003 // with a newly expanded chunk (this happens when _limit was set to the
5ed703250bff 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 1716
diff changeset
8004 // previous _end of the space), so we may have stepped past _limit; see CR 6977970.
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8005 if (addr >= _limit) { // we have swept up to or past the limit: finish up
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8006 assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
8007 "sweep _limit out of bounds");
1720
5ed703250bff 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 1716
diff changeset
8008 assert(addr < _sp->end(), "addr out of bounds");
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8009 // Flush any remaining coterminal free run as a single
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8010 // coalesced chunk to the appropriate free list.
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8011 if (inFreeRange()) {
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8012 assert(freeFinger() < _limit, "finger points too high");
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8013 flush_cur_free_chunk(freeFinger(),
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8014 pointer_delta(addr, freeFinger()));
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8015 if (CMSTraceSweeper) {
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8016 gclog_or_tty->print("Sweep: last chunk: ");
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8017 gclog_or_tty->print("put_free_blk 0x%x ("SIZE_FORMAT") "
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8018 "[coalesced:"SIZE_FORMAT"]\n",
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8019 freeFinger(), pointer_delta(addr, freeFinger()),
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8020 lastFreeRangeCoalesced());
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8021 }
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8022 }
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8023
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8024 // help the iterator loop finish
1720
5ed703250bff 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 1716
diff changeset
8025 return pointer_delta(_sp->end(), addr);
5ed703250bff 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 1716
diff changeset
8026 }
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8027
1720
5ed703250bff 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 1716
diff changeset
8028 assert(addr < _limit, "sweep invariant");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8029 // check if we should yield
a61af66fc99e Initial load
duke
parents:
diff changeset
8030 do_yield_check(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8031 if (fc->isFree()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8032 // Chunk that is already free
a61af66fc99e Initial load
duke
parents:
diff changeset
8033 res = fc->size();
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8034 do_already_free_chunk(fc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8035 debug_only(_sp->verifyFreeLists());
a61af66fc99e Initial load
duke
parents:
diff changeset
8036 assert(res == fc->size(), "Don't expect the size to change");
a61af66fc99e Initial load
duke
parents:
diff changeset
8037 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
8038 _numObjectsAlreadyFree++;
a61af66fc99e Initial load
duke
parents:
diff changeset
8039 _numWordsAlreadyFree += res;
a61af66fc99e Initial load
duke
parents:
diff changeset
8040 )
a61af66fc99e Initial load
duke
parents:
diff changeset
8041 NOT_PRODUCT(_last_fc = fc;)
a61af66fc99e Initial load
duke
parents:
diff changeset
8042 } else if (!_bitMap->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8043 // Chunk is fresh garbage
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8044 res = do_garbage_chunk(fc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8045 debug_only(_sp->verifyFreeLists());
a61af66fc99e Initial load
duke
parents:
diff changeset
8046 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
8047 _numObjectsFreed++;
a61af66fc99e Initial load
duke
parents:
diff changeset
8048 _numWordsFreed += res;
a61af66fc99e Initial load
duke
parents:
diff changeset
8049 )
a61af66fc99e Initial load
duke
parents:
diff changeset
8050 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
8051 // Chunk that is alive.
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8052 res = do_live_chunk(fc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8053 debug_only(_sp->verifyFreeLists());
a61af66fc99e Initial load
duke
parents:
diff changeset
8054 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
8055 _numObjectsLive++;
a61af66fc99e Initial load
duke
parents:
diff changeset
8056 _numWordsLive += res;
a61af66fc99e Initial load
duke
parents:
diff changeset
8057 )
a61af66fc99e Initial load
duke
parents:
diff changeset
8058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8059 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
8060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8061
a61af66fc99e Initial load
duke
parents:
diff changeset
8062 // For the smart allocation, record following
a61af66fc99e Initial load
duke
parents:
diff changeset
8063 // split deaths - a free chunk is removed from its free list because
a61af66fc99e Initial load
duke
parents:
diff changeset
8064 // it is being split into two or more chunks.
a61af66fc99e Initial load
duke
parents:
diff changeset
8065 // split birth - a free chunk is being added to its free list because
a61af66fc99e Initial load
duke
parents:
diff changeset
8066 // a larger free chunk has been split and resulted in this free chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
8067 // coal death - a free chunk is being removed from its free list because
a61af66fc99e Initial load
duke
parents:
diff changeset
8068 // it is being coalesced into a large free chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
8069 // coal birth - a free chunk is being added to its free list because
a61af66fc99e Initial load
duke
parents:
diff changeset
8070 // it was created when two or more free chunks where coalesced into
a61af66fc99e Initial load
duke
parents:
diff changeset
8071 // this free chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
8072 //
a61af66fc99e Initial load
duke
parents:
diff changeset
8073 // These statistics are used to determine the desired number of free
a61af66fc99e Initial load
duke
parents:
diff changeset
8074 // chunks of a given size. The desired number is chosen to be relative
a61af66fc99e Initial load
duke
parents:
diff changeset
8075 // to the end of a CMS sweep. The desired number at the end of a sweep
a61af66fc99e Initial load
duke
parents:
diff changeset
8076 // is the
a61af66fc99e Initial load
duke
parents:
diff changeset
8077 // count-at-end-of-previous-sweep (an amount that was enough)
a61af66fc99e Initial load
duke
parents:
diff changeset
8078 // - count-at-beginning-of-current-sweep (the excess)
a61af66fc99e Initial load
duke
parents:
diff changeset
8079 // + split-births (gains in this size during interval)
a61af66fc99e Initial load
duke
parents:
diff changeset
8080 // - split-deaths (demands on this size during interval)
a61af66fc99e Initial load
duke
parents:
diff changeset
8081 // where the interval is from the end of one sweep to the end of the
a61af66fc99e Initial load
duke
parents:
diff changeset
8082 // next.
a61af66fc99e Initial load
duke
parents:
diff changeset
8083 //
a61af66fc99e Initial load
duke
parents:
diff changeset
8084 // When sweeping the sweeper maintains an accumulated chunk which is
a61af66fc99e Initial load
duke
parents:
diff changeset
8085 // the chunk that is made up of chunks that have been coalesced. That
a61af66fc99e Initial load
duke
parents:
diff changeset
8086 // will be termed the left-hand chunk. A new chunk of garbage that
a61af66fc99e Initial load
duke
parents:
diff changeset
8087 // is being considered for coalescing will be referred to as the
a61af66fc99e Initial load
duke
parents:
diff changeset
8088 // right-hand chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
8089 //
a61af66fc99e Initial load
duke
parents:
diff changeset
8090 // When making a decision on whether to coalesce a right-hand chunk with
a61af66fc99e Initial load
duke
parents:
diff changeset
8091 // the current left-hand chunk, the current count vs. the desired count
a61af66fc99e Initial load
duke
parents:
diff changeset
8092 // of the left-hand chunk is considered. Also if the right-hand chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
8093 // is near the large chunk at the end of the heap (see
a61af66fc99e Initial load
duke
parents:
diff changeset
8094 // ConcurrentMarkSweepGeneration::isNearLargestChunk()), then the
a61af66fc99e Initial load
duke
parents:
diff changeset
8095 // left-hand chunk is coalesced.
a61af66fc99e Initial load
duke
parents:
diff changeset
8096 //
a61af66fc99e Initial load
duke
parents:
diff changeset
8097 // When making a decision about whether to split a chunk, the desired count
a61af66fc99e Initial load
duke
parents:
diff changeset
8098 // vs. the current count of the candidate to be split is also considered.
a61af66fc99e Initial load
duke
parents:
diff changeset
8099 // If the candidate is underpopulated (currently fewer chunks than desired)
a61af66fc99e Initial load
duke
parents:
diff changeset
8100 // a chunk of an overpopulated (currently more chunks than desired) size may
a61af66fc99e Initial load
duke
parents:
diff changeset
8101 // be chosen. The "hint" associated with a free list, if non-null, points
a61af66fc99e Initial load
duke
parents:
diff changeset
8102 // to a free list which may be overpopulated.
a61af66fc99e Initial load
duke
parents:
diff changeset
8103 //
a61af66fc99e Initial load
duke
parents:
diff changeset
8104
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8105 void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8106 size_t size = fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
8107 // Chunks that cannot be coalesced are not in the
a61af66fc99e Initial load
duke
parents:
diff changeset
8108 // free lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
8109 if (CMSTestInFreeList && !fc->cantCoalesce()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8110 assert(_sp->verifyChunkInFreeLists(fc),
a61af66fc99e Initial load
duke
parents:
diff changeset
8111 "free chunk should be in free lists");
a61af66fc99e Initial load
duke
parents:
diff changeset
8112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8113 // a chunk that is already free, should not have been
a61af66fc99e Initial load
duke
parents:
diff changeset
8114 // marked in the bit map
a61af66fc99e Initial load
duke
parents:
diff changeset
8115 HeapWord* addr = (HeapWord*) fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
8116 assert(!_bitMap->isMarked(addr), "free chunk should be unmarked");
a61af66fc99e Initial load
duke
parents:
diff changeset
8117 // Verify that the bit map has no bits marked between
a61af66fc99e Initial load
duke
parents:
diff changeset
8118 // addr and purported end of this block.
a61af66fc99e Initial load
duke
parents:
diff changeset
8119 _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
8120
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8121 // Some chunks cannot be coalesced under any circumstances.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8122 // See the definition of cantCoalesce().
a61af66fc99e Initial load
duke
parents:
diff changeset
8123 if (!fc->cantCoalesce()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8124 // This chunk can potentially be coalesced.
a61af66fc99e Initial load
duke
parents:
diff changeset
8125 if (_sp->adaptive_freelists()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8126 // All the work is done in
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8127 do_post_free_or_garbage_chunk(fc, size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8128 } else { // Not adaptive free lists
a61af66fc99e Initial load
duke
parents:
diff changeset
8129 // this is a free chunk that can potentially be coalesced by the sweeper;
a61af66fc99e Initial load
duke
parents:
diff changeset
8130 if (!inFreeRange()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8131 // if the next chunk is a free block that can't be coalesced
a61af66fc99e Initial load
duke
parents:
diff changeset
8132 // it doesn't make sense to remove this chunk from the free lists
a61af66fc99e Initial load
duke
parents:
diff changeset
8133 FreeChunk* nextChunk = (FreeChunk*)(addr + size);
2136
c91cc404ca46 7011940: iCMS: SIGSEGV in SweepClosure::do_already_free_chunk(FreeChunk*)+0x360
ysr
parents: 2132
diff changeset
8134 assert((HeapWord*)nextChunk <= _sp->end(), "Chunk size out of bounds?");
c91cc404ca46 7011940: iCMS: SIGSEGV in SweepClosure::do_already_free_chunk(FreeChunk*)+0x360
ysr
parents: 2132
diff changeset
8135 if ((HeapWord*)nextChunk < _sp->end() && // There is another free chunk to the right ...
c91cc404ca46 7011940: iCMS: SIGSEGV in SweepClosure::do_already_free_chunk(FreeChunk*)+0x360
ysr
parents: 2132
diff changeset
8136 nextChunk->isFree() && // ... which is free...
c91cc404ca46 7011940: iCMS: SIGSEGV in SweepClosure::do_already_free_chunk(FreeChunk*)+0x360
ysr
parents: 2132
diff changeset
8137 nextChunk->cantCoalesce()) { // ... but can't be coalesced
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8138 // nothing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
8139 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
8140 // Potentially the start of a new free range:
a61af66fc99e Initial load
duke
parents:
diff changeset
8141 // Don't eagerly remove it from the free lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
8142 // No need to remove it if it will just be put
a61af66fc99e Initial load
duke
parents:
diff changeset
8143 // back again. (Also from a pragmatic point of view
a61af66fc99e Initial load
duke
parents:
diff changeset
8144 // if it is a free block in a region that is beyond
a61af66fc99e Initial load
duke
parents:
diff changeset
8145 // any allocated blocks, an assertion will fail)
a61af66fc99e Initial load
duke
parents:
diff changeset
8146 // Remember the start of a free run.
a61af66fc99e Initial load
duke
parents:
diff changeset
8147 initialize_free_range(addr, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
8148 // end - can coalesce with next chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
8149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8150 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
8151 // the midst of a free range, we are coalescing
a61af66fc99e Initial load
duke
parents:
diff changeset
8152 debug_only(record_free_block_coalesced(fc);)
a61af66fc99e Initial load
duke
parents:
diff changeset
8153 if (CMSTraceSweeper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8154 gclog_or_tty->print(" -- pick up free block 0x%x (%d)\n", fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
8155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8156 // remove it from the free lists
a61af66fc99e Initial load
duke
parents:
diff changeset
8157 _sp->removeFreeChunkFromFreeLists(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
8158 set_lastFreeRangeCoalesced(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
8159 // If the chunk is being coalesced and the current free range is
a61af66fc99e Initial load
duke
parents:
diff changeset
8160 // in the free lists, remove the current free range so that it
a61af66fc99e Initial load
duke
parents:
diff changeset
8161 // will be returned to the free lists in its entirety - all
a61af66fc99e Initial load
duke
parents:
diff changeset
8162 // the coalesced pieces included.
a61af66fc99e Initial load
duke
parents:
diff changeset
8163 if (freeRangeInFreeLists()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8164 FreeChunk* ffc = (FreeChunk*) freeFinger();
a61af66fc99e Initial load
duke
parents:
diff changeset
8165 assert(ffc->size() == pointer_delta(addr, freeFinger()),
a61af66fc99e Initial load
duke
parents:
diff changeset
8166 "Size of free range is inconsistent with chunk size.");
a61af66fc99e Initial load
duke
parents:
diff changeset
8167 if (CMSTestInFreeList) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8168 assert(_sp->verifyChunkInFreeLists(ffc),
a61af66fc99e Initial load
duke
parents:
diff changeset
8169 "free range is not in free lists");
a61af66fc99e Initial load
duke
parents:
diff changeset
8170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8171 _sp->removeFreeChunkFromFreeLists(ffc);
a61af66fc99e Initial load
duke
parents:
diff changeset
8172 set_freeRangeInFreeLists(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
8173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8176 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
8177 // Code path common to both original and adaptive free lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
8178
a61af66fc99e Initial load
duke
parents:
diff changeset
8179 // cant coalesce with previous block; this should be treated
a61af66fc99e Initial load
duke
parents:
diff changeset
8180 // as the end of a free run if any
a61af66fc99e Initial load
duke
parents:
diff changeset
8181 if (inFreeRange()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8182 // we kicked some butt; time to pick up the garbage
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8183 assert(freeFinger() < addr, "freeFinger points too high");
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8184 flush_cur_free_chunk(freeFinger(), pointer_delta(addr, freeFinger()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8186 // else, nothing to do, just continue
a61af66fc99e Initial load
duke
parents:
diff changeset
8187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8189
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8190 size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8191 // This is a chunk of garbage. It is not in any free list.
a61af66fc99e Initial load
duke
parents:
diff changeset
8192 // Add it to a free list or let it possibly be coalesced into
a61af66fc99e Initial load
duke
parents:
diff changeset
8193 // a larger chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
8194 HeapWord* addr = (HeapWord*) fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
8195 size_t size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
8196
a61af66fc99e Initial load
duke
parents:
diff changeset
8197 if (_sp->adaptive_freelists()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8198 // Verify that the bit map has no bits marked between
a61af66fc99e Initial load
duke
parents:
diff changeset
8199 // addr and purported end of just dead object.
a61af66fc99e Initial load
duke
parents:
diff changeset
8200 _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
8201
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8202 do_post_free_or_garbage_chunk(fc, size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8203 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
8204 if (!inFreeRange()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8205 // start of a new free range
a61af66fc99e Initial load
duke
parents:
diff changeset
8206 assert(size > 0, "A free range should have a size");
a61af66fc99e Initial load
duke
parents:
diff changeset
8207 initialize_free_range(addr, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
8208
a61af66fc99e Initial load
duke
parents:
diff changeset
8209 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
8210 // this will be swept up when we hit the end of the
a61af66fc99e Initial load
duke
parents:
diff changeset
8211 // free range
a61af66fc99e Initial load
duke
parents:
diff changeset
8212 if (CMSTraceSweeper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8213 gclog_or_tty->print(" -- pick up garbage 0x%x (%d) \n", fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
8214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8215 // If the chunk is being coalesced and the current free range is
a61af66fc99e Initial load
duke
parents:
diff changeset
8216 // in the free lists, remove the current free range so that it
a61af66fc99e Initial load
duke
parents:
diff changeset
8217 // will be returned to the free lists in its entirety - all
a61af66fc99e Initial load
duke
parents:
diff changeset
8218 // the coalesced pieces included.
a61af66fc99e Initial load
duke
parents:
diff changeset
8219 if (freeRangeInFreeLists()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8220 FreeChunk* ffc = (FreeChunk*)freeFinger();
a61af66fc99e Initial load
duke
parents:
diff changeset
8221 assert(ffc->size() == pointer_delta(addr, freeFinger()),
a61af66fc99e Initial load
duke
parents:
diff changeset
8222 "Size of free range is inconsistent with chunk size.");
a61af66fc99e Initial load
duke
parents:
diff changeset
8223 if (CMSTestInFreeList) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8224 assert(_sp->verifyChunkInFreeLists(ffc),
a61af66fc99e Initial load
duke
parents:
diff changeset
8225 "free range is not in free lists");
a61af66fc99e Initial load
duke
parents:
diff changeset
8226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8227 _sp->removeFreeChunkFromFreeLists(ffc);
a61af66fc99e Initial load
duke
parents:
diff changeset
8228 set_freeRangeInFreeLists(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
8229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8230 set_lastFreeRangeCoalesced(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
8231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8232 // this will be swept up when we hit the end of the free range
a61af66fc99e Initial load
duke
parents:
diff changeset
8233
a61af66fc99e Initial load
duke
parents:
diff changeset
8234 // Verify that the bit map has no bits marked between
a61af66fc99e Initial load
duke
parents:
diff changeset
8235 // addr and purported end of just dead object.
a61af66fc99e Initial load
duke
parents:
diff changeset
8236 _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
8237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8238 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
8239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8240
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8241 size_t SweepClosure::do_live_chunk(FreeChunk* fc) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8242 HeapWord* addr = (HeapWord*) fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
8243 // The sweeper has just found a live object. Return any accumulated
a61af66fc99e Initial load
duke
parents:
diff changeset
8244 // left hand chunk to the free lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
8245 if (inFreeRange()) {
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8246 assert(freeFinger() < addr, "freeFinger points too high");
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8247 flush_cur_free_chunk(freeFinger(), pointer_delta(addr, freeFinger()));
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8248 }
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8249
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8250 // This object is live: we'd normally expect this to be
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8251 // an oop, and like to assert the following:
a61af66fc99e Initial load
duke
parents:
diff changeset
8252 // assert(oop(addr)->is_oop(), "live block should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8253 // However, as we commented above, this may be an object whose
a61af66fc99e Initial load
duke
parents:
diff changeset
8254 // header hasn't yet been initialized.
a61af66fc99e Initial load
duke
parents:
diff changeset
8255 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
8256 assert(_bitMap->isMarked(addr), "Tautology for this control point");
a61af66fc99e Initial load
duke
parents:
diff changeset
8257 if (_bitMap->isMarked(addr + 1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8258 // Determine the size from the bit map, rather than trying to
a61af66fc99e Initial load
duke
parents:
diff changeset
8259 // compute it from the object header.
a61af66fc99e Initial load
duke
parents:
diff changeset
8260 HeapWord* nextOneAddr = _bitMap->getNextMarkedWordAddress(addr + 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
8261 size = pointer_delta(nextOneAddr + 1, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8262 assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
a61af66fc99e Initial load
duke
parents:
diff changeset
8263 "alignment problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
8264
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8265 #ifdef DEBUG
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
8266 if (oop(addr)->klass_or_null() != NULL &&
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
8267 ( !_collector->should_unload_classes()
518
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8268 || (oop(addr)->is_parsable()) &&
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8269 oop(addr)->is_conc_safe())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8270 // Ignore mark word because we are running concurrent with mutators
a61af66fc99e Initial load
duke
parents:
diff changeset
8271 assert(oop(addr)->is_oop(true), "live block should be an oop");
518
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8272 // is_conc_safe is checked before performing this assertion
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8273 // because an object that is not is_conc_safe may yet have
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8274 // the return from size() correct.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8275 assert(size ==
a61af66fc99e Initial load
duke
parents:
diff changeset
8276 CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size()),
a61af66fc99e Initial load
duke
parents:
diff changeset
8277 "P-mark and computed size do not agree");
a61af66fc99e Initial load
duke
parents:
diff changeset
8278 }
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8279 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8280
a61af66fc99e Initial load
duke
parents:
diff changeset
8281 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
8282 // This should be an initialized object that's alive.
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 143
diff changeset
8283 assert(oop(addr)->klass_or_null() != NULL &&
94
0834225a7916 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 9
diff changeset
8284 (!_collector->should_unload_classes()
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8285 || oop(addr)->is_parsable()),
a61af66fc99e Initial load
duke
parents:
diff changeset
8286 "Should be an initialized object");
518
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8287 // Note that there are objects used during class redefinition
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8288 // (e.g., merge_cp in VM_RedefineClasses::merge_cp_and_rewrite()
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8289 // which are discarded with their is_conc_safe state still
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8290 // false. These object may be floating garbage so may be
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8291 // seen here. If they are floating garbage their size
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8292 // should be attainable from their klass. Do not that
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
8293 // is_conc_safe() is true for oop(addr).
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8294 // Ignore mark word because we are running concurrent with mutators
a61af66fc99e Initial load
duke
parents:
diff changeset
8295 assert(oop(addr)->is_oop(true), "live block should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8296 // Verify that the bit map has no bits marked between
a61af66fc99e Initial load
duke
parents:
diff changeset
8297 // addr and purported end of this block.
a61af66fc99e Initial load
duke
parents:
diff changeset
8298 size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
8299 assert(size >= 3, "Necessary for Printezis marks to work");
a61af66fc99e Initial load
duke
parents:
diff changeset
8300 assert(!_bitMap->isMarked(addr+1), "Tautology for this control point");
a61af66fc99e Initial load
duke
parents:
diff changeset
8301 DEBUG_ONLY(_bitMap->verifyNoOneBitsInRange(addr+2, addr+size);)
a61af66fc99e Initial load
duke
parents:
diff changeset
8302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8303 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
8304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8305
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8306 void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8307 size_t chunkSize) {
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8308 // do_post_free_or_garbage_chunk() should only be called in the case
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8309 // of the adaptive free list allocator.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8310 bool fcInFreeLists = fc->isFree();
a61af66fc99e Initial load
duke
parents:
diff changeset
8311 assert(_sp->adaptive_freelists(), "Should only be used in this case.");
a61af66fc99e Initial load
duke
parents:
diff changeset
8312 assert((HeapWord*)fc <= _limit, "sweep invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
8313 if (CMSTestInFreeList && fcInFreeLists) {
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8314 assert(_sp->verifyChunkInFreeLists(fc), "free chunk is not in free lists");
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8315 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8316
a61af66fc99e Initial load
duke
parents:
diff changeset
8317 if (CMSTraceSweeper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8318 gclog_or_tty->print_cr(" -- pick up another chunk at 0x%x (%d)", fc, chunkSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
8319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8320
a61af66fc99e Initial load
duke
parents:
diff changeset
8321 HeapWord* addr = (HeapWord*) fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
8322
a61af66fc99e Initial load
duke
parents:
diff changeset
8323 bool coalesce;
a61af66fc99e Initial load
duke
parents:
diff changeset
8324 size_t left = pointer_delta(addr, freeFinger());
a61af66fc99e Initial load
duke
parents:
diff changeset
8325 size_t right = chunkSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
8326 switch (FLSCoalescePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8327 // numeric value forms a coalition aggressiveness metric
a61af66fc99e Initial load
duke
parents:
diff changeset
8328 case 0: { // never coalesce
a61af66fc99e Initial load
duke
parents:
diff changeset
8329 coalesce = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
8330 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
8331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8332 case 1: { // coalesce if left & right chunks on overpopulated lists
a61af66fc99e Initial load
duke
parents:
diff changeset
8333 coalesce = _sp->coalOverPopulated(left) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8334 _sp->coalOverPopulated(right);
a61af66fc99e Initial load
duke
parents:
diff changeset
8335 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
8336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8337 case 2: { // coalesce if left chunk on overpopulated list (default)
a61af66fc99e Initial load
duke
parents:
diff changeset
8338 coalesce = _sp->coalOverPopulated(left);
a61af66fc99e Initial load
duke
parents:
diff changeset
8339 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
8340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8341 case 3: { // coalesce if left OR right chunk on overpopulated list
a61af66fc99e Initial load
duke
parents:
diff changeset
8342 coalesce = _sp->coalOverPopulated(left) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
8343 _sp->coalOverPopulated(right);
a61af66fc99e Initial load
duke
parents:
diff changeset
8344 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
8345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8346 case 4: { // always coalesce
a61af66fc99e Initial load
duke
parents:
diff changeset
8347 coalesce = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
8348 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
8349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8350 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
8351 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
8352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8353
a61af66fc99e Initial load
duke
parents:
diff changeset
8354 // Should the current free range be coalesced?
a61af66fc99e Initial load
duke
parents:
diff changeset
8355 // If the chunk is in a free range and either we decided to coalesce above
a61af66fc99e Initial load
duke
parents:
diff changeset
8356 // or the chunk is near the large block at the end of the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
8357 // (isNearLargestChunk() returns true), then coalesce this chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
8358 bool doCoalesce = inFreeRange() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8359 (coalesce || _g->isNearLargestChunk((HeapWord*)fc));
a61af66fc99e Initial load
duke
parents:
diff changeset
8360 if (doCoalesce) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8361 // Coalesce the current free range on the left with the new
a61af66fc99e Initial load
duke
parents:
diff changeset
8362 // chunk on the right. If either is on a free list,
a61af66fc99e Initial load
duke
parents:
diff changeset
8363 // it must be removed from the list and stashed in the closure.
a61af66fc99e Initial load
duke
parents:
diff changeset
8364 if (freeRangeInFreeLists()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8365 FreeChunk* ffc = (FreeChunk*)freeFinger();
a61af66fc99e Initial load
duke
parents:
diff changeset
8366 assert(ffc->size() == pointer_delta(addr, freeFinger()),
a61af66fc99e Initial load
duke
parents:
diff changeset
8367 "Size of free range is inconsistent with chunk size.");
a61af66fc99e Initial load
duke
parents:
diff changeset
8368 if (CMSTestInFreeList) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8369 assert(_sp->verifyChunkInFreeLists(ffc),
a61af66fc99e Initial load
duke
parents:
diff changeset
8370 "Chunk is not in free lists");
a61af66fc99e Initial load
duke
parents:
diff changeset
8371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8372 _sp->coalDeath(ffc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
8373 _sp->removeFreeChunkFromFreeLists(ffc);
a61af66fc99e Initial load
duke
parents:
diff changeset
8374 set_freeRangeInFreeLists(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
8375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8376 if (fcInFreeLists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8377 _sp->coalDeath(chunkSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
8378 assert(fc->size() == chunkSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
8379 "The chunk has the wrong size or is not in the free lists");
a61af66fc99e Initial load
duke
parents:
diff changeset
8380 _sp->removeFreeChunkFromFreeLists(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
8381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8382 set_lastFreeRangeCoalesced(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
8383 } else { // not in a free range and/or should not coalesce
a61af66fc99e Initial load
duke
parents:
diff changeset
8384 // Return the current free range and start a new one.
a61af66fc99e Initial load
duke
parents:
diff changeset
8385 if (inFreeRange()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8386 // In a free range but cannot coalesce with the right hand chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
8387 // Put the current free range into the free lists.
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8388 flush_cur_free_chunk(freeFinger(),
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8389 pointer_delta(addr, freeFinger()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8391 // Set up for new free range. Pass along whether the right hand
a61af66fc99e Initial load
duke
parents:
diff changeset
8392 // chunk is in the free lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
8393 initialize_free_range((HeapWord*)fc, fcInFreeLists);
a61af66fc99e Initial load
duke
parents:
diff changeset
8394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8395 }
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8396
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8397 void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8398 assert(inFreeRange(), "Should only be called if currently in a free range.");
a61af66fc99e Initial load
duke
parents:
diff changeset
8399 assert(size > 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
8400 "A zero sized chunk cannot be added to the free lists.");
a61af66fc99e Initial load
duke
parents:
diff changeset
8401 if (!freeRangeInFreeLists()) {
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8402 if (CMSTestInFreeList) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8403 FreeChunk* fc = (FreeChunk*) chunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
8404 fc->setSize(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
8405 assert(!_sp->verifyChunkInFreeLists(fc),
a61af66fc99e Initial load
duke
parents:
diff changeset
8406 "chunk should not be in free lists yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
8407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8408 if (CMSTraceSweeper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8409 gclog_or_tty->print_cr(" -- add free block 0x%x (%d) to free lists",
a61af66fc99e Initial load
duke
parents:
diff changeset
8410 chunk, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
8411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8412 // A new free range is going to be starting. The current
a61af66fc99e Initial load
duke
parents:
diff changeset
8413 // free range has not been added to the free lists yet or
a61af66fc99e Initial load
duke
parents:
diff changeset
8414 // was removed so add it back.
a61af66fc99e Initial load
duke
parents:
diff changeset
8415 // If the current free range was coalesced, then the death
a61af66fc99e Initial load
duke
parents:
diff changeset
8416 // of the free range was recorded. Record a birth now.
a61af66fc99e Initial load
duke
parents:
diff changeset
8417 if (lastFreeRangeCoalesced()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8418 _sp->coalBirth(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
8419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8420 _sp->addChunkAndRepairOffsetTable(chunk, size,
a61af66fc99e Initial load
duke
parents:
diff changeset
8421 lastFreeRangeCoalesced());
a61af66fc99e Initial load
duke
parents:
diff changeset
8422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8423 set_inFreeRange(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
8424 set_freeRangeInFreeLists(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
8425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8426
a61af66fc99e Initial load
duke
parents:
diff changeset
8427 // We take a break if we've been at this for a while,
a61af66fc99e Initial load
duke
parents:
diff changeset
8428 // so as to avoid monopolizing the locks involved.
a61af66fc99e Initial load
duke
parents:
diff changeset
8429 void SweepClosure::do_yield_work(HeapWord* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8430 // Return current free chunk being used for coalescing (if any)
a61af66fc99e Initial load
duke
parents:
diff changeset
8431 // to the appropriate freelist. After yielding, the next
a61af66fc99e Initial load
duke
parents:
diff changeset
8432 // free block encountered will start a coalescing range of
a61af66fc99e Initial load
duke
parents:
diff changeset
8433 // free blocks. If the next free block is adjacent to the
a61af66fc99e Initial load
duke
parents:
diff changeset
8434 // chunk just flushed, they will need to wait for the next
a61af66fc99e Initial load
duke
parents:
diff changeset
8435 // sweep to be coalesced.
a61af66fc99e Initial load
duke
parents:
diff changeset
8436 if (inFreeRange()) {
2132
4947ee68d19c 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 1994
diff changeset
8437 flush_cur_free_chunk(freeFinger(), pointer_delta(addr, freeFinger()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8439
a61af66fc99e Initial load
duke
parents:
diff changeset
8440 // First give up the locks, then yield, then re-lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
8441 // We should probably use a constructor/destructor idiom to
a61af66fc99e Initial load
duke
parents:
diff changeset
8442 // do this unlock/lock or modify the MutexUnlocker class to
a61af66fc99e Initial load
duke
parents:
diff changeset
8443 // serve our purpose. XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
8444 assert_lock_strong(_bitMap->lock());
a61af66fc99e Initial load
duke
parents:
diff changeset
8445 assert_lock_strong(_freelistLock);
a61af66fc99e Initial load
duke
parents:
diff changeset
8446 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
a61af66fc99e Initial load
duke
parents:
diff changeset
8447 "CMS thread should hold CMS token");
a61af66fc99e Initial load
duke
parents:
diff changeset
8448 _bitMap->lock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
8449 _freelistLock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
8450 ConcurrentMarkSweepThread::desynchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
8451 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
8452 _collector->stopTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
8453 GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
a61af66fc99e Initial load
duke
parents:
diff changeset
8454 if (PrintCMSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8455 _collector->incrementYields();
a61af66fc99e Initial load
duke
parents:
diff changeset
8456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8457 _collector->icms_wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
8458
a61af66fc99e Initial load
duke
parents:
diff changeset
8459 // See the comment in coordinator_yield()
a61af66fc99e Initial load
duke
parents:
diff changeset
8460 for (unsigned i = 0; i < CMSYieldSleepCount &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8461 ConcurrentMarkSweepThread::should_yield() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8462 !CMSCollector::foregroundGCIsActive(); ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8463 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
8464 ConcurrentMarkSweepThread::acknowledge_yield_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
8465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8466
a61af66fc99e Initial load
duke
parents:
diff changeset
8467 ConcurrentMarkSweepThread::synchronize(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
8468 _freelistLock->lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
8469 _bitMap->lock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
8470 _collector->startTimer();
a61af66fc99e Initial load
duke
parents:
diff changeset
8471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8472
a61af66fc99e Initial load
duke
parents:
diff changeset
8473 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
8474 // This is actually very useful in a product build if it can
a61af66fc99e Initial load
duke
parents:
diff changeset
8475 // be called from the debugger. Compile it into the product
a61af66fc99e Initial load
duke
parents:
diff changeset
8476 // as needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
8477 bool debug_verifyChunkInFreeLists(FreeChunk* fc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8478 return debug_cms_space->verifyChunkInFreeLists(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
8479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8480
a61af66fc99e Initial load
duke
parents:
diff changeset
8481 void SweepClosure::record_free_block_coalesced(FreeChunk* fc) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
8482 if (CMSTraceSweeper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8483 gclog_or_tty->print("Sweep:coal_free_blk 0x%x (%d)\n", fc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
8484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8486 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
8487
a61af66fc99e Initial load
duke
parents:
diff changeset
8488 // CMSIsAliveClosure
a61af66fc99e Initial load
duke
parents:
diff changeset
8489 bool CMSIsAliveClosure::do_object_b(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8490 HeapWord* addr = (HeapWord*)obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
8491 return addr != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8492 (!_span.contains(addr) || _bit_map->isMarked(addr));
a61af66fc99e Initial load
duke
parents:
diff changeset
8493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8494
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8495 CMSKeepAliveClosure::CMSKeepAliveClosure( CMSCollector* collector,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8496 MemRegion span,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8497 CMSBitMap* bit_map, CMSMarkStack* mark_stack,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8498 CMSMarkStack* revisit_stack, bool cpc):
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8499 KlassRememberingOopClosure(collector, NULL, revisit_stack),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8500 _span(span),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8501 _bit_map(bit_map),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8502 _mark_stack(mark_stack),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8503 _concurrent_precleaning(cpc) {
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8504 assert(!_span.is_empty(), "Empty span could spell trouble");
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8505 }
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8506
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8507
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8508 // CMSKeepAliveClosure: the serial version
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8509 void CMSKeepAliveClosure::do_oop(oop obj) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8510 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8511 if (_span.contains(addr) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8512 !_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8513 _bit_map->mark(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
8514 bool simulate_overflow = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
8515 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
8516 if (CMSMarkStackOverflowALot &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8517 _collector->simulate_overflow()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8518 // simulate a stack overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
8519 simulate_overflow = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
8520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8521 )
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8522 if (simulate_overflow || !_mark_stack->push(obj)) {
452
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8523 if (_concurrent_precleaning) {
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8524 // We dirty the overflown object and let the remark
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8525 // phase deal with it.
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8526 assert(_collector->overflow_list_is_empty(), "Error");
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8527 // In the case of object arrays, we need to dirty all of
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8528 // the cards that the object spans. No locking or atomics
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8529 // are needed since no one else can be mutating the mod union
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8530 // table.
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8531 if (obj->is_objArray()) {
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8532 size_t sz = obj->size();
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8533 HeapWord* end_card_addr =
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8534 (HeapWord*)round_to((intptr_t)(addr+sz), CardTableModRefBS::card_size);
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8535 MemRegion redirty_range = MemRegion(addr, end_card_addr);
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8536 assert(!redirty_range.is_empty(), "Arithmetical tautology");
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8537 _collector->_modUnionTable.mark_range(redirty_range);
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8538 } else {
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8539 _collector->_modUnionTable.mark(addr);
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8540 }
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8541 _collector->_ser_kac_preclean_ovflw++;
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8542 } else {
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8543 _collector->push_on_overflow_list(obj);
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8544 _collector->_ser_kac_ovflw++;
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8545 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8549
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8550 void CMSKeepAliveClosure::do_oop(oop* p) { CMSKeepAliveClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8551 void CMSKeepAliveClosure::do_oop(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8552
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8553 // CMSParKeepAliveClosure: a parallel version of the above.
a61af66fc99e Initial load
duke
parents:
diff changeset
8554 // The work queues are private to each closure (thread),
a61af66fc99e Initial load
duke
parents:
diff changeset
8555 // but (may be) available for stealing by other threads.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8556 void CMSParKeepAliveClosure::do_oop(oop obj) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8557 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8558 if (_span.contains(addr) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8559 !_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8560 // In general, during recursive tracing, several threads
a61af66fc99e Initial load
duke
parents:
diff changeset
8561 // may be concurrently getting here; the first one to
a61af66fc99e Initial load
duke
parents:
diff changeset
8562 // "tag" it, claims it.
a61af66fc99e Initial load
duke
parents:
diff changeset
8563 if (_bit_map->par_mark(addr)) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8564 bool res = _work_queue->push(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8565 assert(res, "Low water mark should be much less than capacity");
a61af66fc99e Initial load
duke
parents:
diff changeset
8566 // Do a recursive trim in the hope that this will keep
a61af66fc99e Initial load
duke
parents:
diff changeset
8567 // stack usage lower, but leave some oops for potential stealers
a61af66fc99e Initial load
duke
parents:
diff changeset
8568 trim_queue(_low_water_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
8569 } // Else, another thread got there first
a61af66fc99e Initial load
duke
parents:
diff changeset
8570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8572
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8573 void CMSParKeepAliveClosure::do_oop(oop* p) { CMSParKeepAliveClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8574 void CMSParKeepAliveClosure::do_oop(narrowOop* p) { CMSParKeepAliveClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8575
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8576 void CMSParKeepAliveClosure::trim_queue(uint max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8577 while (_work_queue->size() > max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8578 oop new_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
8579 if (_work_queue->pop_local(new_oop)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8580 assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8581 assert(_bit_map->isMarked((HeapWord*)new_oop),
a61af66fc99e Initial load
duke
parents:
diff changeset
8582 "no white objects on this stack!");
a61af66fc99e Initial load
duke
parents:
diff changeset
8583 assert(_span.contains((HeapWord*)new_oop), "Out of bounds oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8584 // iterate over the oops in this oop, marking and pushing
a61af66fc99e Initial load
duke
parents:
diff changeset
8585 // the ones in CMS heap (i.e. in _span).
a61af66fc99e Initial load
duke
parents:
diff changeset
8586 new_oop->oop_iterate(&_mark_and_push);
a61af66fc99e Initial load
duke
parents:
diff changeset
8587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8590
935
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8591 CMSInnerParMarkAndPushClosure::CMSInnerParMarkAndPushClosure(
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8592 CMSCollector* collector,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8593 MemRegion span, CMSBitMap* bit_map,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8594 CMSMarkStack* revisit_stack,
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8595 OopTaskQueue* work_queue):
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8596 Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8597 _span(span),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8598 _bit_map(bit_map),
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8599 _work_queue(work_queue) { }
05f89f00a864 6798898: CMS: bugs related to class unloading
jmasa
parents: 798
diff changeset
8600
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8601 void CMSInnerParMarkAndPushClosure::do_oop(oop obj) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8602 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8603 if (_span.contains(addr) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8604 !_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8605 if (_bit_map->par_mark(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8606 bool simulate_overflow = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
8607 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
8608 if (CMSMarkStackOverflowALot &&
a61af66fc99e Initial load
duke
parents:
diff changeset
8609 _collector->par_simulate_overflow()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8610 // simulate a stack overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
8611 simulate_overflow = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
8612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8613 )
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8614 if (simulate_overflow || !_work_queue->push(obj)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8615 _collector->par_push_on_overflow_list(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8616 _collector->_par_kac_ovflw++;
a61af66fc99e Initial load
duke
parents:
diff changeset
8617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8618 } // Else another thread got there already
a61af66fc99e Initial load
duke
parents:
diff changeset
8619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8620 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8621
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8622 void CMSInnerParMarkAndPushClosure::do_oop(oop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8623 void CMSInnerParMarkAndPushClosure::do_oop(narrowOop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8624
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8625 //////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
8626 // CMSExpansionCause /////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
8627 //////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
8628 const char* CMSExpansionCause::to_string(CMSExpansionCause::Cause cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8629 switch (cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8630 case _no_expansion:
a61af66fc99e Initial load
duke
parents:
diff changeset
8631 return "No expansion";
a61af66fc99e Initial load
duke
parents:
diff changeset
8632 case _satisfy_free_ratio:
a61af66fc99e Initial load
duke
parents:
diff changeset
8633 return "Free ratio";
a61af66fc99e Initial load
duke
parents:
diff changeset
8634 case _satisfy_promotion:
a61af66fc99e Initial load
duke
parents:
diff changeset
8635 return "Satisfy promotion";
a61af66fc99e Initial load
duke
parents:
diff changeset
8636 case _satisfy_allocation:
a61af66fc99e Initial load
duke
parents:
diff changeset
8637 return "allocation";
a61af66fc99e Initial load
duke
parents:
diff changeset
8638 case _allocate_par_lab:
a61af66fc99e Initial load
duke
parents:
diff changeset
8639 return "Par LAB";
a61af66fc99e Initial load
duke
parents:
diff changeset
8640 case _allocate_par_spooling_space:
a61af66fc99e Initial load
duke
parents:
diff changeset
8641 return "Par Spooling Space";
a61af66fc99e Initial load
duke
parents:
diff changeset
8642 case _adaptive_size_policy:
a61af66fc99e Initial load
duke
parents:
diff changeset
8643 return "Ergonomics";
a61af66fc99e Initial load
duke
parents:
diff changeset
8644 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
8645 return "unknown";
a61af66fc99e Initial load
duke
parents:
diff changeset
8646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8648
a61af66fc99e Initial load
duke
parents:
diff changeset
8649 void CMSDrainMarkingStackClosure::do_void() {
a61af66fc99e Initial load
duke
parents:
diff changeset
8650 // the max number to take from overflow list at a time
a61af66fc99e Initial load
duke
parents:
diff changeset
8651 const size_t num = _mark_stack->capacity()/4;
452
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8652 assert(!_concurrent_precleaning || _collector->overflow_list_is_empty(),
00b023ae2d78 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 360
diff changeset
8653 "Overflow list should be NULL during concurrent phases");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8654 while (!_mark_stack->isEmpty() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
8655 // if stack is empty, check the overflow list
a61af66fc99e Initial load
duke
parents:
diff changeset
8656 _collector->take_from_overflow_list(num, _mark_stack)) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8657 oop obj = _mark_stack->pop();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8658 HeapWord* addr = (HeapWord*)obj;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8659 assert(_span.contains(addr), "Should be within span");
a61af66fc99e Initial load
duke
parents:
diff changeset
8660 assert(_bit_map->isMarked(addr), "Should be marked");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8661 assert(obj->is_oop(), "Should be an oop");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 94
diff changeset
8662 obj->oop_iterate(_keep_alive);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8665
a61af66fc99e Initial load
duke
parents:
diff changeset
8666 void CMSParDrainMarkingStackClosure::do_void() {
a61af66fc99e Initial load
duke
parents:
diff changeset
8667 // drain queue
a61af66fc99e Initial load
duke
parents:
diff changeset
8668 trim_queue(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
8669 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8670
a61af66fc99e Initial load
duke
parents:
diff changeset
8671 // Trim our work_queue so its length is below max at return
a61af66fc99e Initial load
duke
parents:
diff changeset
8672 void CMSParDrainMarkingStackClosure::trim_queue(uint max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8673 while (_work_queue->size() > max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8674 oop new_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
8675 if (_work_queue->pop_local(new_oop)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8676 assert(new_oop->is_oop(), "Expected an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8677 assert(_bit_map->isMarked((HeapWord*)new_oop),
a61af66fc99e Initial load
duke
parents:
diff changeset
8678 "no white objects on this stack!");
a61af66fc99e Initial load
duke
parents:
diff changeset
8679 assert(_span.contains((HeapWord*)new_oop), "Out of bounds oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8680 // iterate over the oops in this oop, marking and pushing
a61af66fc99e Initial load
duke
parents:
diff changeset
8681 // the ones in CMS heap (i.e. in _span).
a61af66fc99e Initial load
duke
parents:
diff changeset
8682 new_oop->oop_iterate(&_mark_and_push);
a61af66fc99e Initial load
duke
parents:
diff changeset
8683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8686
a61af66fc99e Initial load
duke
parents:
diff changeset
8687 ////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
8688 // Support for Marking Stack Overflow list handling and related code
a61af66fc99e Initial load
duke
parents:
diff changeset
8689 ////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
8690 // Much of the following code is similar in shape and spirit to the
a61af66fc99e Initial load
duke
parents:
diff changeset
8691 // code used in ParNewGC. We should try and share that code
a61af66fc99e Initial load
duke
parents:
diff changeset
8692 // as much as possible in the future.
a61af66fc99e Initial load
duke
parents:
diff changeset
8693
a61af66fc99e Initial load
duke
parents:
diff changeset
8694 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
8695 // Debugging support for CMSStackOverflowALot
a61af66fc99e Initial load
duke
parents:
diff changeset
8696
a61af66fc99e Initial load
duke
parents:
diff changeset
8697 // It's OK to call this multi-threaded; the worst thing
a61af66fc99e Initial load
duke
parents:
diff changeset
8698 // that can happen is that we'll get a bunch of closely
a61af66fc99e Initial load
duke
parents:
diff changeset
8699 // spaced simulated oveflows, but that's OK, in fact
a61af66fc99e Initial load
duke
parents:
diff changeset
8700 // probably good as it would exercise the overflow code
a61af66fc99e Initial load
duke
parents:
diff changeset
8701 // under contention.
a61af66fc99e Initial load
duke
parents:
diff changeset
8702 bool CMSCollector::simulate_overflow() {
a61af66fc99e Initial load
duke
parents:
diff changeset
8703 if (_overflow_counter-- <= 0) { // just being defensive
a61af66fc99e Initial load
duke
parents:
diff changeset
8704 _overflow_counter = CMSMarkStackOverflowInterval;
a61af66fc99e Initial load
duke
parents:
diff changeset
8705 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
8706 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
8707 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
8708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8709 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8710
a61af66fc99e Initial load
duke
parents:
diff changeset
8711 bool CMSCollector::par_simulate_overflow() {
a61af66fc99e Initial load
duke
parents:
diff changeset
8712 return simulate_overflow();
a61af66fc99e Initial load
duke
parents:
diff changeset
8713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8714 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
8715
a61af66fc99e Initial load
duke
parents:
diff changeset
8716 // Single-threaded
a61af66fc99e Initial load
duke
parents:
diff changeset
8717 bool CMSCollector::take_from_overflow_list(size_t num, CMSMarkStack* stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8718 assert(stack->isEmpty(), "Expected precondition");
a61af66fc99e Initial load
duke
parents:
diff changeset
8719 assert(stack->capacity() > num, "Shouldn't bite more than can chew");
a61af66fc99e Initial load
duke
parents:
diff changeset
8720 size_t i = num;
a61af66fc99e Initial load
duke
parents:
diff changeset
8721 oop cur = _overflow_list;
a61af66fc99e Initial load
duke
parents:
diff changeset
8722 const markOop proto = markOopDesc::prototype();
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8723 NOT_PRODUCT(ssize_t n = 0;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8724 for (oop next; i > 0 && cur != NULL; cur = next, i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8725 next = oop(cur->mark());
a61af66fc99e Initial load
duke
parents:
diff changeset
8726 cur->set_mark(proto); // until proven otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
8727 assert(cur->is_oop(), "Should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8728 bool res = stack->push(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
8729 assert(res, "Bit off more than can chew?");
a61af66fc99e Initial load
duke
parents:
diff changeset
8730 NOT_PRODUCT(n++;)
a61af66fc99e Initial load
duke
parents:
diff changeset
8731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8732 _overflow_list = cur;
a61af66fc99e Initial load
duke
parents:
diff changeset
8733 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
8734 assert(_num_par_pushes >= n, "Too many pops?");
a61af66fc99e Initial load
duke
parents:
diff changeset
8735 _num_par_pushes -=n;
a61af66fc99e Initial load
duke
parents:
diff changeset
8736 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
8737 return !stack->isEmpty();
a61af66fc99e Initial load
duke
parents:
diff changeset
8738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8739
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8740 #define BUSY (oop(0x1aff1aff))
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8741 // (MT-safe) Get a prefix of at most "num" from the list.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8742 // The overflow list is chained through the mark word of
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8743 // each object in the list. We fetch the entire list,
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8744 // break off a prefix of the right size and return the
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8745 // remainder. If other threads try to take objects from
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8746 // the overflow list at that time, they will wait for
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8747 // some time to see if data becomes available. If (and
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8748 // only if) another thread places one or more object(s)
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8749 // on the global list before we have returned the suffix
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8750 // to the global list, we will walk down our local list
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8751 // to find its end and append the global list to
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8752 // our suffix before returning it. This suffix walk can
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8753 // prove to be expensive (quadratic in the amount of traffic)
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8754 // when there are many objects in the overflow list and
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8755 // there is much producer-consumer contention on the list.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8756 // *NOTE*: The overflow list manipulation code here and
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8757 // in ParNewGeneration:: are very similar in shape,
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8758 // except that in the ParNew case we use the old (from/eden)
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8759 // copy of the object to thread the list via its klass word.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8760 // Because of the common code, if you make any changes in
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8761 // the code below, please check the ParNew version to see if
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8762 // similar changes might be needed.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8763 // CR 6797058 has been filed to consolidate the common code.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8764 bool CMSCollector::par_take_from_overflow_list(size_t num,
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
8765 OopTaskQueue* work_q,
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
8766 int no_of_gc_threads) {
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8767 assert(work_q->size() == 0, "First empty local work queue");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8768 assert(num < work_q->max_elems(), "Can't bite more than we can chew");
a61af66fc99e Initial load
duke
parents:
diff changeset
8769 if (_overflow_list == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8770 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
8771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8772 // Grab the entire list; we'll put back a suffix
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8773 oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8774 Thread* tid = Thread::current();
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
8775 // Before "no_of_gc_threads" was introduced CMSOverflowSpinCount was
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
8776 // set to ParallelGCThreads.
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1777
diff changeset
8777 size_t CMSOverflowSpinCount = (size_t) no_of_gc_threads; // was ParallelGCThreads;
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8778 size_t sleep_time_millis = MAX2((size_t)1, num/100);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8779 // If the list is busy, we spin for a short while,
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8780 // sleeping between attempts to get the list.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8781 for (size_t spin = 0; prefix == BUSY && spin < CMSOverflowSpinCount; spin++) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8782 os::sleep(tid, sleep_time_millis, false);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8783 if (_overflow_list == NULL) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8784 // Nothing left to take
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8785 return false;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8786 } else if (_overflow_list != BUSY) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8787 // Try and grab the prefix
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8788 prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8789 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8790 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8791 // If the list was found to be empty, or we spun long
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8792 // enough, we give up and return empty-handed. If we leave
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8793 // the list in the BUSY state below, it must be the case that
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8794 // some other thread holds the overflow list and will set it
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8795 // to a non-BUSY state in the future.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8796 if (prefix == NULL || prefix == BUSY) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8797 // Nothing to take or waited long enough
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8798 if (prefix == NULL) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8799 // Write back the NULL in case we overwrote it with BUSY above
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8800 // and it is still the same value.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8801 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8802 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8803 return false;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8804 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8805 assert(prefix != NULL && prefix != BUSY, "Error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8806 size_t i = num;
a61af66fc99e Initial load
duke
parents:
diff changeset
8807 oop cur = prefix;
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8808 // Walk down the first "num" objects, unless we reach the end.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8809 for (; i > 1 && cur->mark() != NULL; cur = oop(cur->mark()), i--);
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8810 if (cur->mark() == NULL) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8811 // We have "num" or fewer elements in the list, so there
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8812 // is nothing to return to the global list.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8813 // Write back the NULL in lieu of the BUSY we wrote
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8814 // above, if it is still the same value.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8815 if (_overflow_list == BUSY) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8816 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8817 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8818 } else {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8819 // Chop off the suffix and rerturn it to the global list.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8820 assert(cur->mark() != BUSY, "Error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8821 oop suffix_head = cur->mark(); // suffix will be put back on global list
a61af66fc99e Initial load
duke
parents:
diff changeset
8822 cur->set_mark(NULL); // break off suffix
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8823 // It's possible that the list is still in the empty(busy) state
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8824 // we left it in a short while ago; in that case we may be
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8825 // able to place back the suffix without incurring the cost
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8826 // of a walk down the list.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8827 oop observed_overflow_list = _overflow_list;
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8828 oop cur_overflow_list = observed_overflow_list;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8829 bool attached = false;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8830 while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8831 observed_overflow_list =
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8832 (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8833 if (cur_overflow_list == observed_overflow_list) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8834 attached = true;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8835 break;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8836 } else cur_overflow_list = observed_overflow_list;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8837 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8838 if (!attached) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8839 // Too bad, someone else sneaked in (at least) an element; we'll need
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8840 // to do a splice. Find tail of suffix so we can prepend suffix to global
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8841 // list.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8842 for (cur = suffix_head; cur->mark() != NULL; cur = (oop)(cur->mark()));
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8843 oop suffix_tail = cur;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8844 assert(suffix_tail != NULL && suffix_tail->mark() == NULL,
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8845 "Tautology");
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8846 observed_overflow_list = _overflow_list;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8847 do {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8848 cur_overflow_list = observed_overflow_list;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8849 if (cur_overflow_list != BUSY) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8850 // Do the splice ...
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8851 suffix_tail->set_mark(markOop(cur_overflow_list));
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8852 } else { // cur_overflow_list == BUSY
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8853 suffix_tail->set_mark(NULL);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8854 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8855 // ... and try to place spliced list back on overflow_list ...
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8856 observed_overflow_list =
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8857 (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8858 } while (cur_overflow_list != observed_overflow_list);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8859 // ... until we have succeeded in doing so.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8860 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8862
a61af66fc99e Initial load
duke
parents:
diff changeset
8863 // Push the prefix elements on work_q
a61af66fc99e Initial load
duke
parents:
diff changeset
8864 assert(prefix != NULL, "control point invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
8865 const markOop proto = markOopDesc::prototype();
a61af66fc99e Initial load
duke
parents:
diff changeset
8866 oop next;
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8867 NOT_PRODUCT(ssize_t n = 0;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8868 for (cur = prefix; cur != NULL; cur = next) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8869 next = oop(cur->mark());
a61af66fc99e Initial load
duke
parents:
diff changeset
8870 cur->set_mark(proto); // until proven otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
8871 assert(cur->is_oop(), "Should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8872 bool res = work_q->push(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
8873 assert(res, "Bit off more than we can chew?");
a61af66fc99e Initial load
duke
parents:
diff changeset
8874 NOT_PRODUCT(n++;)
a61af66fc99e Initial load
duke
parents:
diff changeset
8875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8876 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
8877 assert(_num_par_pushes >= n, "Too many pops?");
a61af66fc99e Initial load
duke
parents:
diff changeset
8878 Atomic::add_ptr(-(intptr_t)n, &_num_par_pushes);
a61af66fc99e Initial load
duke
parents:
diff changeset
8879 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
8880 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
8881 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8882
a61af66fc99e Initial load
duke
parents:
diff changeset
8883 // Single-threaded
a61af66fc99e Initial load
duke
parents:
diff changeset
8884 void CMSCollector::push_on_overflow_list(oop p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8885 NOT_PRODUCT(_num_par_pushes++;)
a61af66fc99e Initial load
duke
parents:
diff changeset
8886 assert(p->is_oop(), "Not an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8887 preserve_mark_if_necessary(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
8888 p->set_mark((markOop)_overflow_list);
a61af66fc99e Initial load
duke
parents:
diff changeset
8889 _overflow_list = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
8890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8891
a61af66fc99e Initial load
duke
parents:
diff changeset
8892 // Multi-threaded; use CAS to prepend to overflow list
a61af66fc99e Initial load
duke
parents:
diff changeset
8893 void CMSCollector::par_push_on_overflow_list(oop p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8894 NOT_PRODUCT(Atomic::inc_ptr(&_num_par_pushes);)
a61af66fc99e Initial load
duke
parents:
diff changeset
8895 assert(p->is_oop(), "Not an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8896 par_preserve_mark_if_necessary(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
8897 oop observed_overflow_list = _overflow_list;
a61af66fc99e Initial load
duke
parents:
diff changeset
8898 oop cur_overflow_list;
a61af66fc99e Initial load
duke
parents:
diff changeset
8899 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
8900 cur_overflow_list = observed_overflow_list;
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8901 if (cur_overflow_list != BUSY) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8902 p->set_mark(markOop(cur_overflow_list));
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8903 } else {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8904 p->set_mark(NULL);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8905 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8906 observed_overflow_list =
a61af66fc99e Initial load
duke
parents:
diff changeset
8907 (oop) Atomic::cmpxchg_ptr(p, &_overflow_list, cur_overflow_list);
a61af66fc99e Initial load
duke
parents:
diff changeset
8908 } while (cur_overflow_list != observed_overflow_list);
a61af66fc99e Initial load
duke
parents:
diff changeset
8909 }
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8910 #undef BUSY
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8911
a61af66fc99e Initial load
duke
parents:
diff changeset
8912 // Single threaded
a61af66fc99e Initial load
duke
parents:
diff changeset
8913 // General Note on GrowableArray: pushes may silently fail
a61af66fc99e Initial load
duke
parents:
diff changeset
8914 // because we are (temporarily) out of C-heap for expanding
a61af66fc99e Initial load
duke
parents:
diff changeset
8915 // the stack. The problem is quite ubiquitous and affects
a61af66fc99e Initial load
duke
parents:
diff changeset
8916 // a lot of code in the JVM. The prudent thing for GrowableArray
a61af66fc99e Initial load
duke
parents:
diff changeset
8917 // to do (for now) is to exit with an error. However, that may
a61af66fc99e Initial load
duke
parents:
diff changeset
8918 // be too draconian in some cases because the caller may be
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 518
diff changeset
8919 // able to recover without much harm. For such cases, we
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8920 // should probably introduce a "soft_push" method which returns
a61af66fc99e Initial load
duke
parents:
diff changeset
8921 // an indication of success or failure with the assumption that
a61af66fc99e Initial load
duke
parents:
diff changeset
8922 // the caller may be able to recover from a failure; code in
a61af66fc99e Initial load
duke
parents:
diff changeset
8923 // the VM can then be changed, incrementally, to deal with such
a61af66fc99e Initial load
duke
parents:
diff changeset
8924 // failures where possible, thus, incrementally hardening the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
8925 // in such low resource situations.
a61af66fc99e Initial load
duke
parents:
diff changeset
8926 void CMSCollector::preserve_mark_work(oop p, markOop m) {
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8927 _preserved_oop_stack.push(p);
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8928 _preserved_mark_stack.push(m);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8929 assert(m == p->mark(), "Mark word changed");
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8930 assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8931 "bijection");
a61af66fc99e Initial load
duke
parents:
diff changeset
8932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8933
a61af66fc99e Initial load
duke
parents:
diff changeset
8934 // Single threaded
a61af66fc99e Initial load
duke
parents:
diff changeset
8935 void CMSCollector::preserve_mark_if_necessary(oop p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8936 markOop m = p->mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
8937 if (m->must_be_preserved(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8938 preserve_mark_work(p, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
8939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8941
a61af66fc99e Initial load
duke
parents:
diff changeset
8942 void CMSCollector::par_preserve_mark_if_necessary(oop p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8943 markOop m = p->mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
8944 if (m->must_be_preserved(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
8945 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
8946 // Even though we read the mark word without holding
a61af66fc99e Initial load
duke
parents:
diff changeset
8947 // the lock, we are assured that it will not change
a61af66fc99e Initial load
duke
parents:
diff changeset
8948 // because we "own" this oop, so no other thread can
a61af66fc99e Initial load
duke
parents:
diff changeset
8949 // be trying to push it on the overflow list; see
a61af66fc99e Initial load
duke
parents:
diff changeset
8950 // the assertion in preserve_mark_work() that checks
a61af66fc99e Initial load
duke
parents:
diff changeset
8951 // that m == p->mark().
a61af66fc99e Initial load
duke
parents:
diff changeset
8952 preserve_mark_work(p, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
8953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8955
a61af66fc99e Initial load
duke
parents:
diff changeset
8956 // We should be able to do this multi-threaded,
a61af66fc99e Initial load
duke
parents:
diff changeset
8957 // a chunk of stack being a task (this is
a61af66fc99e Initial load
duke
parents:
diff changeset
8958 // correct because each oop only ever appears
a61af66fc99e Initial load
duke
parents:
diff changeset
8959 // once in the overflow list. However, it's
a61af66fc99e Initial load
duke
parents:
diff changeset
8960 // not very easy to completely overlap this with
a61af66fc99e Initial load
duke
parents:
diff changeset
8961 // other operations, so will generally not be done
a61af66fc99e Initial load
duke
parents:
diff changeset
8962 // until all work's been completed. Because we
a61af66fc99e Initial load
duke
parents:
diff changeset
8963 // expect the preserved oop stack (set) to be small,
a61af66fc99e Initial load
duke
parents:
diff changeset
8964 // it's probably fine to do this single-threaded.
a61af66fc99e Initial load
duke
parents:
diff changeset
8965 // We can explore cleverer concurrent/overlapped/parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
8966 // processing of preserved marks if we feel the
a61af66fc99e Initial load
duke
parents:
diff changeset
8967 // need for this in the future. Stack overflow should
a61af66fc99e Initial load
duke
parents:
diff changeset
8968 // be so rare in practice and, when it happens, its
a61af66fc99e Initial load
duke
parents:
diff changeset
8969 // effect on performance so great that this will
a61af66fc99e Initial load
duke
parents:
diff changeset
8970 // likely just be in the noise anyway.
a61af66fc99e Initial load
duke
parents:
diff changeset
8971 void CMSCollector::restore_preserved_marks_if_any() {
a61af66fc99e Initial load
duke
parents:
diff changeset
8972 assert(SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
8973 "world should be stopped");
a61af66fc99e Initial load
duke
parents:
diff changeset
8974 assert(Thread::current()->is_ConcurrentGC_thread() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
8975 Thread::current()->is_VM_thread(),
a61af66fc99e Initial load
duke
parents:
diff changeset
8976 "should be single-threaded");
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8977 assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8978 "bijection");
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8979
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8980 while (!_preserved_oop_stack.is_empty()) {
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8981 oop p = _preserved_oop_stack.pop();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8982 assert(p->is_oop(), "Should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
8983 assert(_span.contains(p), "oop should be in _span");
a61af66fc99e Initial load
duke
parents:
diff changeset
8984 assert(p->mark() == markOopDesc::prototype(),
a61af66fc99e Initial load
duke
parents:
diff changeset
8985 "Set when taken from overflow list");
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8986 markOop m = _preserved_mark_stack.pop();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8987 p->set_mark(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
8988 }
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8989 assert(_preserved_mark_stack.is_empty() && _preserved_oop_stack.is_empty(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8990 "stacks were cleared above");
a61af66fc99e Initial load
duke
parents:
diff changeset
8991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8992
a61af66fc99e Initial load
duke
parents:
diff changeset
8993 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
8994 bool CMSCollector::no_preserved_marks() const {
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
8995 return _preserved_mark_stack.is_empty() && _preserved_oop_stack.is_empty();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
8996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
8997 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
8998
a61af66fc99e Initial load
duke
parents:
diff changeset
8999 CMSAdaptiveSizePolicy* ASConcurrentMarkSweepGeneration::cms_size_policy() const
a61af66fc99e Initial load
duke
parents:
diff changeset
9000 {
a61af66fc99e Initial load
duke
parents:
diff changeset
9001 GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
9002 CMSAdaptiveSizePolicy* size_policy =
a61af66fc99e Initial load
duke
parents:
diff changeset
9003 (CMSAdaptiveSizePolicy*) gch->gen_policy()->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
9004 assert(size_policy->is_gc_cms_adaptive_size_policy(),
a61af66fc99e Initial load
duke
parents:
diff changeset
9005 "Wrong type for size policy");
a61af66fc99e Initial load
duke
parents:
diff changeset
9006 return size_policy;
a61af66fc99e Initial load
duke
parents:
diff changeset
9007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9008
a61af66fc99e Initial load
duke
parents:
diff changeset
9009 void ASConcurrentMarkSweepGeneration::resize(size_t cur_promo_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
9010 size_t desired_promo_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9011 if (cur_promo_size < desired_promo_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9012 size_t expand_bytes = desired_promo_size - cur_promo_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
9013 if (PrintAdaptiveSizePolicy && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9014 gclog_or_tty->print_cr(" ASConcurrentMarkSweepGeneration::resize "
a61af66fc99e Initial load
duke
parents:
diff changeset
9015 "Expanding tenured generation by " SIZE_FORMAT " (bytes)",
a61af66fc99e Initial load
duke
parents:
diff changeset
9016 expand_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
9017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9018 expand(expand_bytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
9019 MinHeapDeltaBytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
9020 CMSExpansionCause::_adaptive_size_policy);
a61af66fc99e Initial load
duke
parents:
diff changeset
9021 } else if (desired_promo_size < cur_promo_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9022 size_t shrink_bytes = cur_promo_size - desired_promo_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
9023 if (PrintAdaptiveSizePolicy && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9024 gclog_or_tty->print_cr(" ASConcurrentMarkSweepGeneration::resize "
a61af66fc99e Initial load
duke
parents:
diff changeset
9025 "Shrinking tenured generation by " SIZE_FORMAT " (bytes)",
a61af66fc99e Initial load
duke
parents:
diff changeset
9026 shrink_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
9027 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9028 shrink(shrink_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
9029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9031
a61af66fc99e Initial load
duke
parents:
diff changeset
9032 CMSGCAdaptivePolicyCounters* ASConcurrentMarkSweepGeneration::gc_adaptive_policy_counters() {
a61af66fc99e Initial load
duke
parents:
diff changeset
9033 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
9034 CMSGCAdaptivePolicyCounters* counters =
a61af66fc99e Initial load
duke
parents:
diff changeset
9035 (CMSGCAdaptivePolicyCounters*) gch->collector_policy()->counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
9036 assert(counters->kind() == GCPolicyCounters::CMSGCAdaptivePolicyCountersKind,
a61af66fc99e Initial load
duke
parents:
diff changeset
9037 "Wrong kind of counters");
a61af66fc99e Initial load
duke
parents:
diff changeset
9038 return counters;
a61af66fc99e Initial load
duke
parents:
diff changeset
9039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9040
a61af66fc99e Initial load
duke
parents:
diff changeset
9041
a61af66fc99e Initial load
duke
parents:
diff changeset
9042 void ASConcurrentMarkSweepGeneration::update_counters() {
a61af66fc99e Initial load
duke
parents:
diff changeset
9043 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9044 _space_counters->update_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
9045 _gen_counters->update_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
9046 CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
9047 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
9048 CMSGCStats* gc_stats_l = (CMSGCStats*) gc_stats();
a61af66fc99e Initial load
duke
parents:
diff changeset
9049 assert(gc_stats_l->kind() == GCStats::CMSGCStatsKind,
a61af66fc99e Initial load
duke
parents:
diff changeset
9050 "Wrong gc statistics type");
a61af66fc99e Initial load
duke
parents:
diff changeset
9051 counters->update_counters(gc_stats_l);
a61af66fc99e Initial load
duke
parents:
diff changeset
9052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9054
a61af66fc99e Initial load
duke
parents:
diff changeset
9055 void ASConcurrentMarkSweepGeneration::update_counters(size_t used) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9056 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9057 _space_counters->update_used(used);
a61af66fc99e Initial load
duke
parents:
diff changeset
9058 _space_counters->update_capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
9059 _gen_counters->update_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
9060
a61af66fc99e Initial load
duke
parents:
diff changeset
9061 CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
9062 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
9063 CMSGCStats* gc_stats_l = (CMSGCStats*) gc_stats();
a61af66fc99e Initial load
duke
parents:
diff changeset
9064 assert(gc_stats_l->kind() == GCStats::CMSGCStatsKind,
a61af66fc99e Initial load
duke
parents:
diff changeset
9065 "Wrong gc statistics type");
a61af66fc99e Initial load
duke
parents:
diff changeset
9066 counters->update_counters(gc_stats_l);
a61af66fc99e Initial load
duke
parents:
diff changeset
9067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9068 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9069
a61af66fc99e Initial load
duke
parents:
diff changeset
9070 // The desired expansion delta is computed so that:
a61af66fc99e Initial load
duke
parents:
diff changeset
9071 // . desired free percentage or greater is used
a61af66fc99e Initial load
duke
parents:
diff changeset
9072 void ASConcurrentMarkSweepGeneration::compute_new_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
9073 assert_locked_or_safepoint(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
9074
a61af66fc99e Initial load
duke
parents:
diff changeset
9075 GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
9076
a61af66fc99e Initial load
duke
parents:
diff changeset
9077 // If incremental collection failed, we just want to expand
a61af66fc99e Initial load
duke
parents:
diff changeset
9078 // to the limit.
a61af66fc99e Initial load
duke
parents:
diff changeset
9079 if (incremental_collection_failed()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9080 clear_incremental_collection_failed();
a61af66fc99e Initial load
duke
parents:
diff changeset
9081 grow_to_reserved();
a61af66fc99e Initial load
duke
parents:
diff changeset
9082 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
9083 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9084
a61af66fc99e Initial load
duke
parents:
diff changeset
9085 assert(UseAdaptiveSizePolicy, "Should be using adaptive sizing");
a61af66fc99e Initial load
duke
parents:
diff changeset
9086
a61af66fc99e Initial load
duke
parents:
diff changeset
9087 assert(gch->kind() == CollectedHeap::GenCollectedHeap,
a61af66fc99e Initial load
duke
parents:
diff changeset
9088 "Wrong type of heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
9089 int prev_level = level() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
9090 assert(prev_level >= 0, "The cms generation is the lowest generation");
a61af66fc99e Initial load
duke
parents:
diff changeset
9091 Generation* prev_gen = gch->get_gen(prev_level);
a61af66fc99e Initial load
duke
parents:
diff changeset
9092 assert(prev_gen->kind() == Generation::ASParNew,
a61af66fc99e Initial load
duke
parents:
diff changeset
9093 "Wrong type of young generation");
a61af66fc99e Initial load
duke
parents:
diff changeset
9094 ParNewGeneration* younger_gen = (ParNewGeneration*) prev_gen;
a61af66fc99e Initial load
duke
parents:
diff changeset
9095 size_t cur_eden = younger_gen->eden()->capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
9096 CMSAdaptiveSizePolicy* size_policy = cms_size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
9097 size_t cur_promo = free();
a61af66fc99e Initial load
duke
parents:
diff changeset
9098 size_policy->compute_tenured_generation_free_space(cur_promo,
a61af66fc99e Initial load
duke
parents:
diff changeset
9099 max_available(),
a61af66fc99e Initial load
duke
parents:
diff changeset
9100 cur_eden);
a61af66fc99e Initial load
duke
parents:
diff changeset
9101 resize(cur_promo, size_policy->promo_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
9102
a61af66fc99e Initial load
duke
parents:
diff changeset
9103 // Record the new size of the space in the cms generation
a61af66fc99e Initial load
duke
parents:
diff changeset
9104 // that is available for promotions. This is temporary.
a61af66fc99e Initial load
duke
parents:
diff changeset
9105 // It should be the desired promo size.
a61af66fc99e Initial load
duke
parents:
diff changeset
9106 size_policy->avg_cms_promo()->sample(free());
a61af66fc99e Initial load
duke
parents:
diff changeset
9107 size_policy->avg_old_live()->sample(used());
a61af66fc99e Initial load
duke
parents:
diff changeset
9108
a61af66fc99e Initial load
duke
parents:
diff changeset
9109 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9110 CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
9111 counters->update_cms_capacity_counter(capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
9112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9114
a61af66fc99e Initial load
duke
parents:
diff changeset
9115 void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9116 assert_locked_or_safepoint(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
9117 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
9118 HeapWord* old_end = _cmsSpace->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
9119 HeapWord* unallocated_start = _cmsSpace->unallocated_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
9120 assert(old_end >= unallocated_start, "Miscalculation of unallocated_start");
a61af66fc99e Initial load
duke
parents:
diff changeset
9121 FreeChunk* chunk_at_end = find_chunk_at_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
9122 if (chunk_at_end == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9123 // No room to shrink
a61af66fc99e Initial load
duke
parents:
diff changeset
9124 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9125 gclog_or_tty->print_cr("No room to shrink: old_end "
a61af66fc99e Initial load
duke
parents:
diff changeset
9126 PTR_FORMAT " unallocated_start " PTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
9127 " chunk_at_end " PTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
9128 old_end, unallocated_start, chunk_at_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
9129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9130 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
9131 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
9132
a61af66fc99e Initial load
duke
parents:
diff changeset
9133 // Find the chunk at the end of the space and determine
a61af66fc99e Initial load
duke
parents:
diff changeset
9134 // how much it can be shrunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
9135 size_t shrinkable_size_in_bytes = chunk_at_end->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
9136 size_t aligned_shrinkable_size_in_bytes =
a61af66fc99e Initial load
duke
parents:
diff changeset
9137 align_size_down(shrinkable_size_in_bytes, os::vm_page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
9138 assert(unallocated_start <= chunk_at_end->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
9139 "Inconsistent chunk at end of space");
a61af66fc99e Initial load
duke
parents:
diff changeset
9140 size_t bytes = MIN2(desired_bytes, aligned_shrinkable_size_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
9141 size_t word_size_before = heap_word_size(_virtual_space.committed_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
9142
a61af66fc99e Initial load
duke
parents:
diff changeset
9143 // Shrink the underlying space
a61af66fc99e Initial load
duke
parents:
diff changeset
9144 _virtual_space.shrink_by(bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
9145 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9146 gclog_or_tty->print_cr("ConcurrentMarkSweepGeneration::shrink_by:"
a61af66fc99e Initial load
duke
parents:
diff changeset
9147 " desired_bytes " SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
9148 " shrinkable_size_in_bytes " SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
9149 " aligned_shrinkable_size_in_bytes " SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
9150 " bytes " SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
9151 desired_bytes, shrinkable_size_in_bytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
9152 aligned_shrinkable_size_in_bytes, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
9153 gclog_or_tty->print_cr(" old_end " SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
9154 " unallocated_start " SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
9155 old_end, unallocated_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
9156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9157
a61af66fc99e Initial load
duke
parents:
diff changeset
9158 // If the space did shrink (shrinking is not guaranteed),
a61af66fc99e Initial load
duke
parents:
diff changeset
9159 // shrink the chunk at the end by the appropriate amount.
a61af66fc99e Initial load
duke
parents:
diff changeset
9160 if (((HeapWord*)_virtual_space.high()) < old_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9161 size_t new_word_size =
a61af66fc99e Initial load
duke
parents:
diff changeset
9162 heap_word_size(_virtual_space.committed_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
9163
a61af66fc99e Initial load
duke
parents:
diff changeset
9164 // Have to remove the chunk from the dictionary because it is changing
a61af66fc99e Initial load
duke
parents:
diff changeset
9165 // size and might be someplace elsewhere in the dictionary.
a61af66fc99e Initial load
duke
parents:
diff changeset
9166
a61af66fc99e Initial load
duke
parents:
diff changeset
9167 // Get the chunk at end, shrink it, and put it
a61af66fc99e Initial load
duke
parents:
diff changeset
9168 // back.
a61af66fc99e Initial load
duke
parents:
diff changeset
9169 _cmsSpace->removeChunkFromDictionary(chunk_at_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
9170 size_t word_size_change = word_size_before - new_word_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
9171 size_t chunk_at_end_old_size = chunk_at_end->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
9172 assert(chunk_at_end_old_size >= word_size_change,
a61af66fc99e Initial load
duke
parents:
diff changeset
9173 "Shrink is too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
9174 chunk_at_end->setSize(chunk_at_end_old_size -
a61af66fc99e Initial load
duke
parents:
diff changeset
9175 word_size_change);
a61af66fc99e Initial load
duke
parents:
diff changeset
9176 _cmsSpace->freed((HeapWord*) chunk_at_end->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
9177 word_size_change);
a61af66fc99e Initial load
duke
parents:
diff changeset
9178
a61af66fc99e Initial load
duke
parents:
diff changeset
9179 _cmsSpace->returnChunkToDictionary(chunk_at_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
9180
a61af66fc99e Initial load
duke
parents:
diff changeset
9181 MemRegion mr(_cmsSpace->bottom(), new_word_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
9182 _bts->resize(new_word_size); // resize the block offset shared array
a61af66fc99e Initial load
duke
parents:
diff changeset
9183 Universe::heap()->barrier_set()->resize_covered_region(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
9184 _cmsSpace->assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
9185 _cmsSpace->set_end((HeapWord*)_virtual_space.high());
a61af66fc99e Initial load
duke
parents:
diff changeset
9186
a61af66fc99e Initial load
duke
parents:
diff changeset
9187 NOT_PRODUCT(_cmsSpace->dictionary()->verify());
a61af66fc99e Initial load
duke
parents:
diff changeset
9188
a61af66fc99e Initial load
duke
parents:
diff changeset
9189 // update the space and generation capacity counters
a61af66fc99e Initial load
duke
parents:
diff changeset
9190 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9191 _space_counters->update_capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
9192 _gen_counters->update_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
9193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9194
a61af66fc99e Initial load
duke
parents:
diff changeset
9195 if (Verbose && PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9196 size_t new_mem_size = _virtual_space.committed_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
9197 size_t old_mem_size = new_mem_size + bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
9198 gclog_or_tty->print_cr("Shrinking %s from %ldK by %ldK to %ldK",
a61af66fc99e Initial load
duke
parents:
diff changeset
9199 name(), old_mem_size/K, bytes/K, new_mem_size/K);
a61af66fc99e Initial load
duke
parents:
diff changeset
9200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9202
a61af66fc99e Initial load
duke
parents:
diff changeset
9203 assert(_cmsSpace->unallocated_block() <= _cmsSpace->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
9204 "Inconsistency at end of space");
a61af66fc99e Initial load
duke
parents:
diff changeset
9205 assert(chunk_at_end->end() == _cmsSpace->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
9206 "Shrinking is inconsistent");
a61af66fc99e Initial load
duke
parents:
diff changeset
9207 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
9208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9210
a61af66fc99e Initial load
duke
parents:
diff changeset
9211 // Transfer some number of overflown objects to usual marking
a61af66fc99e Initial load
duke
parents:
diff changeset
9212 // stack. Return true if some objects were transferred.
a61af66fc99e Initial load
duke
parents:
diff changeset
9213 bool MarkRefsIntoAndScanClosure::take_from_overflow_list() {
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 628
diff changeset
9214 size_t num = MIN2((size_t)(_mark_stack->capacity() - _mark_stack->length())/4,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9215 (size_t)ParGCDesiredObjsFromOverflowList);
a61af66fc99e Initial load
duke
parents:
diff changeset
9216
a61af66fc99e Initial load
duke
parents:
diff changeset
9217 bool res = _collector->take_from_overflow_list(num, _mark_stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
9218 assert(_collector->overflow_list_is_empty() || res,
a61af66fc99e Initial load
duke
parents:
diff changeset
9219 "If list is not empty, we should have taken something");
a61af66fc99e Initial load
duke
parents:
diff changeset
9220 assert(!res || !_mark_stack->isEmpty(),
a61af66fc99e Initial load
duke
parents:
diff changeset
9221 "If we took something, it should now be on our stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
9222 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
9223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9224
a61af66fc99e Initial load
duke
parents:
diff changeset
9225 size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9226 size_t res = _sp->block_size_no_stall(addr, _collector);
a61af66fc99e Initial load
duke
parents:
diff changeset
9227 if (_sp->block_is_obj(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9228 if (_live_bit_map->isMarked(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
9229 // It can't have been dead in a previous cycle
a61af66fc99e Initial load
duke
parents:
diff changeset
9230 guarantee(!_dead_bit_map->isMarked(addr), "No resurrection!");
a61af66fc99e Initial load
duke
parents:
diff changeset
9231 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
9232 _dead_bit_map->mark(addr); // mark the dead object
a61af66fc99e Initial load
duke
parents:
diff changeset
9233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
9234 }
2226
c5a923563727 6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents: 2177
diff changeset
9235 // Could be 0, if the block size could not be computed without stalling.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
9236 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
9237 }
1703
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9238
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9239 TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(CMSCollector::CollectorState phase): TraceMemoryManagerStats() {
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9240
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9241 switch (phase) {
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9242 case CMSCollector::InitialMarking:
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9243 initialize(true /* fullGC */ ,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9244 true /* recordGCBeginTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9245 true /* recordPreGCUsage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9246 false /* recordPeakUsage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9247 false /* recordPostGCusage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9248 true /* recordAccumulatedGCTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9249 false /* recordGCEndTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9250 false /* countCollection */ );
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9251 break;
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9252
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9253 case CMSCollector::FinalMarking:
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9254 initialize(true /* fullGC */ ,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9255 false /* recordGCBeginTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9256 false /* recordPreGCUsage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9257 false /* recordPeakUsage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9258 false /* recordPostGCusage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9259 true /* recordAccumulatedGCTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9260 false /* recordGCEndTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9261 false /* countCollection */ );
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9262 break;
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9263
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9264 case CMSCollector::Sweeping:
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9265 initialize(true /* fullGC */ ,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9266 false /* recordGCBeginTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9267 false /* recordPreGCUsage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9268 true /* recordPeakUsage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9269 true /* recordPostGCusage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9270 false /* recordAccumulatedGCTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9271 true /* recordGCEndTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9272 true /* countCollection */ );
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9273 break;
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9274
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9275 default:
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9276 ShouldNotReachHere();
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9277 }
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9278 }
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9279
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9280 // when bailing out of cms in concurrent mode failure
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9281 TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(): TraceMemoryManagerStats() {
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9282 initialize(true /* fullGC */ ,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9283 true /* recordGCBeginTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9284 true /* recordPreGCUsage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9285 true /* recordPeakUsage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9286 true /* recordPostGCusage */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9287 true /* recordAccumulatedGCTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9288 true /* recordGCEndTime */,
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9289 true /* countCollection */ );
f6f3eef8a521 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 1579
diff changeset
9290 }