Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp @ 6027:8a2e5a6a19a4
7143490: G1: Remove HeapRegion::_top_at_conc_mark_count
Summary: Removed the HeapRegion::_top_at_conc_mark_count field. It is no longer needed as a result of the changes for 6888336 and 7127706. Refactored the closures that finalize and verify the liveness counting data so that common functionality was placed into a base class.
Reviewed-by: brutisso, tonyp
author | johnc |
---|---|
date | Wed, 25 Apr 2012 10:23:12 -0700 |
parents | de268c8a8075 |
children | a7509aff1b06 |
rev | line source |
---|---|
0 | 1 /* |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
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:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp" | |
28 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" | |
29 #include "memory/genCollectedHeap.hpp" | |
30 #include "oops/instanceRefKlass.hpp" | |
31 #include "oops/oop.inline.hpp" | |
32 #include "runtime/init.hpp" | |
33 #include "runtime/interfaceSupport.hpp" | |
34 #include "runtime/java.hpp" | |
35 #include "runtime/javaCalls.hpp" | |
36 #include "runtime/mutexLocker.hpp" | |
37 #include "runtime/os.hpp" | |
38 #include "runtime/vmThread.hpp" | |
0 | 39 |
40 // ======= Concurrent Mark Sweep Thread ======== | |
41 | |
42 // The CMS thread is created when Concurrent Mark Sweep is used in the | |
43 // older of two generations in a generational memory system. | |
44 | |
45 ConcurrentMarkSweepThread* | |
46 ConcurrentMarkSweepThread::_cmst = NULL; | |
47 CMSCollector* ConcurrentMarkSweepThread::_collector = NULL; | |
48 bool ConcurrentMarkSweepThread::_should_terminate = false; | |
49 int ConcurrentMarkSweepThread::_CMS_flag = CMS_nil; | |
50 | |
51 volatile jint ConcurrentMarkSweepThread::_pending_yields = 0; | |
52 volatile jint ConcurrentMarkSweepThread::_pending_decrements = 0; | |
53 | |
2365
a181f3a124dd
6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents:
1972
diff
changeset
|
54 volatile jint ConcurrentMarkSweepThread::_icms_disabled = 0; |
0 | 55 volatile bool ConcurrentMarkSweepThread::_should_run = false; |
56 // When icms is enabled, the icms thread is stopped until explicitly | |
57 // started. | |
58 volatile bool ConcurrentMarkSweepThread::_should_stop = true; | |
59 | |
60 SurrogateLockerThread* | |
61 ConcurrentMarkSweepThread::_slt = NULL; | |
62 SurrogateLockerThread::SLT_msg_type | |
63 ConcurrentMarkSweepThread::_sltBuffer = SurrogateLockerThread::empty; | |
64 Monitor* | |
65 ConcurrentMarkSweepThread::_sltMonitor = NULL; | |
66 | |
67 ConcurrentMarkSweepThread::ConcurrentMarkSweepThread(CMSCollector* collector) | |
68 : ConcurrentGCThread() { | |
69 assert(UseConcMarkSweepGC, "UseConcMarkSweepGC should be set"); | |
70 assert(_cmst == NULL, "CMS thread already created"); | |
71 _cmst = this; | |
72 assert(_collector == NULL, "Collector already set"); | |
73 _collector = collector; | |
74 | |
75 set_name("Concurrent Mark-Sweep GC Thread"); | |
76 | |
77 if (os::create_thread(this, os::cgc_thread)) { | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
78 // An old comment here said: "Priority should be just less |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
79 // than that of VMThread". Since the VMThread runs at |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
80 // NearMaxPriority, the old comment was inaccurate, but |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
81 // changing the default priority to NearMaxPriority-1 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
82 // could change current behavior, so the default of |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
83 // NearMaxPriority stays in place. |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
84 // |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
85 // Note that there's a possibility of the VMThread |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
86 // starving if UseCriticalCMSThreadPriority is on. |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
87 // That won't happen on Solaris for various reasons, |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
88 // but may well happen on non-Solaris platforms. |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
89 int native_prio; |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
90 if (UseCriticalCMSThreadPriority) { |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
91 native_prio = os::java_to_os_priority[CriticalPriority]; |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
92 } else { |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
93 native_prio = os::java_to_os_priority[NearMaxPriority]; |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
94 } |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
95 os::set_native_priority(this, native_prio); |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
2365
diff
changeset
|
96 |
0 | 97 if (!DisableStartThread) { |
98 os::start_thread(this); | |
99 } | |
100 } | |
101 _sltMonitor = SLT_lock; | |
2365
a181f3a124dd
6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents:
1972
diff
changeset
|
102 assert(!CMSIncrementalMode || icms_is_enabled(), "Error"); |
0 | 103 } |
104 | |
105 void ConcurrentMarkSweepThread::run() { | |
106 assert(this == cmst(), "just checking"); | |
107 | |
108 this->record_stack_base_and_size(); | |
109 this->initialize_thread_local_storage(); | |
110 this->set_active_handles(JNIHandleBlock::allocate_block()); | |
111 // From this time Thread::current() should be working. | |
112 assert(this == Thread::current(), "just checking"); | |
113 if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) { | |
114 warning("Couldn't bind CMS thread to processor %u", CPUForCMSThread); | |
115 } | |
116 // Wait until Universe::is_fully_initialized() | |
117 { | |
118 CMSLoopCountWarn loopX("CMS::run", "waiting for " | |
119 "Universe::is_fully_initialized()", 2); | |
120 MutexLockerEx x(CGC_lock, true); | |
121 set_CMS_flag(CMS_cms_wants_token); | |
122 // Wait until Universe is initialized and all initialization is completed. | |
123 while (!is_init_completed() && !Universe::is_fully_initialized() && | |
124 !_should_terminate) { | |
125 CGC_lock->wait(true, 200); | |
126 loopX.tick(); | |
127 } | |
128 // Wait until the surrogate locker thread that will do | |
129 // pending list locking on our behalf has been created. | |
130 // We cannot start the SLT thread ourselves since we need | |
131 // to be a JavaThread to do so. | |
132 CMSLoopCountWarn loopY("CMS::run", "waiting for SLT installation", 2); | |
133 while (_slt == NULL && !_should_terminate) { | |
134 CGC_lock->wait(true, 200); | |
135 loopY.tick(); | |
136 } | |
137 clear_CMS_flag(CMS_cms_wants_token); | |
138 } | |
139 | |
140 while (!_should_terminate) { | |
141 sleepBeforeNextCycle(); | |
142 if (_should_terminate) break; | |
143 _collector->collect_in_background(false); // !clear_all_soft_refs | |
144 } | |
145 assert(_should_terminate, "just checking"); | |
146 // Check that the state of any protocol for synchronization | |
147 // between background (CMS) and foreground collector is "clean" | |
148 // (i.e. will not potentially block the foreground collector, | |
149 // requiring action by us). | |
150 verify_ok_to_terminate(); | |
151 // Signal that it is terminated | |
152 { | |
153 MutexLockerEx mu(Terminator_lock, | |
154 Mutex::_no_safepoint_check_flag); | |
155 assert(_cmst == this, "Weird!"); | |
156 _cmst = NULL; | |
157 Terminator_lock->notify(); | |
158 } | |
159 | |
160 // Thread destructor usually does this.. | |
161 ThreadLocalStorage::set_thread(NULL); | |
162 } | |
163 | |
164 #ifndef PRODUCT | |
165 void ConcurrentMarkSweepThread::verify_ok_to_terminate() const { | |
166 assert(!(CGC_lock->owned_by_self() || cms_thread_has_cms_token() || | |
167 cms_thread_wants_cms_token()), | |
168 "Must renounce all worldly possessions and desires for nirvana"); | |
169 _collector->verify_ok_to_terminate(); | |
170 } | |
171 #endif | |
172 | |
173 // create and start a new ConcurrentMarkSweep Thread for given CMS generation | |
174 ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::start(CMSCollector* collector) { | |
175 if (!_should_terminate) { | |
176 assert(cmst() == NULL, "start() called twice?"); | |
177 ConcurrentMarkSweepThread* th = new ConcurrentMarkSweepThread(collector); | |
178 assert(cmst() == th, "Where did the just-created CMS thread go?"); | |
179 return th; | |
180 } | |
181 return NULL; | |
182 } | |
183 | |
184 void ConcurrentMarkSweepThread::stop() { | |
185 if (CMSIncrementalMode) { | |
186 // Disable incremental mode and wake up the thread so it notices the change. | |
187 disable_icms(); | |
188 start_icms(); | |
189 } | |
190 // it is ok to take late safepoints here, if needed | |
191 { | |
192 MutexLockerEx x(Terminator_lock); | |
193 _should_terminate = true; | |
194 } | |
195 { // Now post a notify on CGC_lock so as to nudge | |
196 // CMS thread(s) that might be slumbering in | |
197 // sleepBeforeNextCycle. | |
198 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); | |
199 CGC_lock->notify_all(); | |
200 } | |
201 { // Now wait until (all) CMS thread(s) have exited | |
202 MutexLockerEx x(Terminator_lock); | |
203 while(cmst() != NULL) { | |
204 Terminator_lock->wait(); | |
205 } | |
206 } | |
207 } | |
208 | |
209 void ConcurrentMarkSweepThread::threads_do(ThreadClosure* tc) { | |
210 assert(tc != NULL, "Null ThreadClosure"); | |
211 if (_cmst != NULL) { | |
212 tc->do_thread(_cmst); | |
213 } | |
214 assert(Universe::is_fully_initialized(), | |
215 "Called too early, make sure heap is fully initialized"); | |
216 if (_collector != NULL) { | |
217 AbstractWorkGang* gang = _collector->conc_workers(); | |
218 if (gang != NULL) { | |
219 gang->threads_do(tc); | |
220 } | |
221 } | |
222 } | |
223 | |
224 void ConcurrentMarkSweepThread::print_on(outputStream* st) const { | |
225 st->print("\"%s\" ", name()); | |
226 Thread::print_on(st); | |
227 st->cr(); | |
228 } | |
229 | |
230 void ConcurrentMarkSweepThread::print_all_on(outputStream* st) { | |
231 if (_cmst != NULL) { | |
232 _cmst->print_on(st); | |
233 } | |
234 if (_collector != NULL) { | |
235 AbstractWorkGang* gang = _collector->conc_workers(); | |
236 if (gang != NULL) { | |
237 gang->print_worker_threads_on(st); | |
238 } | |
239 } | |
240 } | |
241 | |
242 void ConcurrentMarkSweepThread::synchronize(bool is_cms_thread) { | |
243 assert(UseConcMarkSweepGC, "just checking"); | |
244 | |
245 MutexLockerEx x(CGC_lock, | |
246 Mutex::_no_safepoint_check_flag); | |
247 if (!is_cms_thread) { | |
248 assert(Thread::current()->is_VM_thread(), "Not a VM thread"); | |
249 CMSSynchronousYieldRequest yr; | |
250 while (CMS_flag_is_set(CMS_cms_has_token)) { | |
251 // indicate that we want to get the token | |
252 set_CMS_flag(CMS_vm_wants_token); | |
253 CGC_lock->wait(true); | |
254 } | |
255 // claim the token and proceed | |
256 clear_CMS_flag(CMS_vm_wants_token); | |
257 set_CMS_flag(CMS_vm_has_token); | |
258 } else { | |
259 assert(Thread::current()->is_ConcurrentGC_thread(), | |
260 "Not a CMS thread"); | |
261 // The following barrier assumes there's only one CMS thread. | |
262 // This will need to be modified is there are more CMS threads than one. | |
263 while (CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token)) { | |
264 set_CMS_flag(CMS_cms_wants_token); | |
265 CGC_lock->wait(true); | |
266 } | |
267 // claim the token | |
268 clear_CMS_flag(CMS_cms_wants_token); | |
269 set_CMS_flag(CMS_cms_has_token); | |
270 } | |
271 } | |
272 | |
273 void ConcurrentMarkSweepThread::desynchronize(bool is_cms_thread) { | |
274 assert(UseConcMarkSweepGC, "just checking"); | |
275 | |
276 MutexLockerEx x(CGC_lock, | |
277 Mutex::_no_safepoint_check_flag); | |
278 if (!is_cms_thread) { | |
279 assert(Thread::current()->is_VM_thread(), "Not a VM thread"); | |
280 assert(CMS_flag_is_set(CMS_vm_has_token), "just checking"); | |
281 clear_CMS_flag(CMS_vm_has_token); | |
282 if (CMS_flag_is_set(CMS_cms_wants_token)) { | |
283 // wake-up a waiting CMS thread | |
284 CGC_lock->notify(); | |
285 } | |
286 assert(!CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token), | |
287 "Should have been cleared"); | |
288 } else { | |
289 assert(Thread::current()->is_ConcurrentGC_thread(), | |
290 "Not a CMS thread"); | |
291 assert(CMS_flag_is_set(CMS_cms_has_token), "just checking"); | |
292 clear_CMS_flag(CMS_cms_has_token); | |
293 if (CMS_flag_is_set(CMS_vm_wants_token)) { | |
294 // wake-up a waiting VM thread | |
295 CGC_lock->notify(); | |
296 } | |
297 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), | |
298 "Should have been cleared"); | |
299 } | |
300 } | |
301 | |
1887
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
302 // Wait until the next synchronous GC, a concurrent full gc request, |
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
303 // or a timeout, whichever is earlier. |
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
304 void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) { |
0 | 305 MutexLockerEx x(CGC_lock, |
306 Mutex::_no_safepoint_check_flag); | |
1887
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
307 if (_should_terminate || _collector->_full_gc_requested) { |
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
308 return; |
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
309 } |
0 | 310 set_CMS_flag(CMS_cms_wants_token); // to provoke notifies |
1887
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
311 CGC_lock->wait(Mutex::_no_safepoint_check_flag, t_millis); |
0 | 312 clear_CMS_flag(CMS_cms_wants_token); |
313 assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), | |
314 "Should not be set"); | |
315 } | |
316 | |
317 void ConcurrentMarkSweepThread::sleepBeforeNextCycle() { | |
318 while (!_should_terminate) { | |
319 if (CMSIncrementalMode) { | |
320 icms_wait(); | |
321 return; | |
322 } else { | |
1887
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
323 // Wait until the next synchronous GC, a concurrent full gc |
cd3ef3fd20dd
6992998: CMSWaitDuration=0 causes hangs with +ExplicitGCInvokesConcurrent
ysr
parents:
1552
diff
changeset
|
324 // request or a timeout, whichever is earlier. |
0 | 325 wait_on_cms_lock(CMSWaitDuration); |
326 } | |
327 // Check if we should start a CMS collection cycle | |
328 if (_collector->shouldConcurrentCollect()) { | |
329 return; | |
330 } | |
331 // .. collection criterion not yet met, let's go back | |
332 // and wait some more | |
333 } | |
334 } | |
335 | |
336 // Incremental CMS | |
337 void ConcurrentMarkSweepThread::start_icms() { | |
338 assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); | |
339 MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); | |
340 trace_state("start_icms"); | |
341 _should_run = true; | |
342 iCMS_lock->notify_all(); | |
343 } | |
344 | |
345 void ConcurrentMarkSweepThread::stop_icms() { | |
346 assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); | |
347 MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); | |
348 if (!_should_stop) { | |
349 trace_state("stop_icms"); | |
350 _should_stop = true; | |
351 _should_run = false; | |
352 asynchronous_yield_request(); | |
353 iCMS_lock->notify_all(); | |
354 } | |
355 } | |
356 | |
357 void ConcurrentMarkSweepThread::icms_wait() { | |
358 assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); | |
2365
a181f3a124dd
6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents:
1972
diff
changeset
|
359 if (_should_stop && icms_is_enabled()) { |
0 | 360 MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); |
361 trace_state("pause_icms"); | |
362 _collector->stats().stop_cms_timer(); | |
2365
a181f3a124dd
6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents:
1972
diff
changeset
|
363 while(!_should_run && icms_is_enabled()) { |
0 | 364 iCMS_lock->wait(Mutex::_no_safepoint_check_flag); |
365 } | |
366 _collector->stats().start_cms_timer(); | |
367 _should_stop = false; | |
368 trace_state("pause_icms end"); | |
369 } | |
370 } | |
371 | |
372 // Note: this method, although exported by the ConcurrentMarkSweepThread, | |
373 // which is a non-JavaThread, can only be called by a JavaThread. | |
374 // Currently this is done at vm creation time (post-vm-init) by the | |
375 // main/Primordial (Java)Thread. | |
376 // XXX Consider changing this in the future to allow the CMS thread | |
377 // itself to create this thread? | |
378 void ConcurrentMarkSweepThread::makeSurrogateLockerThread(TRAPS) { | |
379 assert(UseConcMarkSweepGC, "SLT thread needed only for CMS GC"); | |
380 assert(_slt == NULL, "SLT already created"); | |
381 _slt = SurrogateLockerThread::make(THREAD); | |
382 } |