src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,469 @@
     1.4 +/*
     1.5 + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#include "precompiled.hpp"
    1.29 +#include "classfile/systemDictionary.hpp"
    1.30 +#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp"
    1.31 +#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
    1.32 +#include "memory/genCollectedHeap.hpp"
    1.33 +#include "oops/instanceRefKlass.hpp"
    1.34 +#include "oops/oop.inline.hpp"
    1.35 +#include "runtime/init.hpp"
    1.36 +#include "runtime/interfaceSupport.hpp"
    1.37 +#include "runtime/java.hpp"
    1.38 +#include "runtime/javaCalls.hpp"
    1.39 +#include "runtime/mutexLocker.hpp"
    1.40 +#include "runtime/os.hpp"
    1.41 +#include "runtime/vmThread.hpp"
    1.42 +
    1.43 +// ======= Concurrent Mark Sweep Thread ========
    1.44 +
    1.45 +// The CMS thread is created when Concurrent Mark Sweep is used in the
    1.46 +// older of two generations in a generational memory system.
    1.47 +
    1.48 +ConcurrentMarkSweepThread*
    1.49 +     ConcurrentMarkSweepThread::_cmst     = NULL;
    1.50 +CMSCollector* ConcurrentMarkSweepThread::_collector = NULL;
    1.51 +bool ConcurrentMarkSweepThread::_should_terminate = false;
    1.52 +int  ConcurrentMarkSweepThread::_CMS_flag         = CMS_nil;
    1.53 +
    1.54 +volatile jint ConcurrentMarkSweepThread::_pending_yields      = 0;
    1.55 +volatile jint ConcurrentMarkSweepThread::_pending_decrements  = 0;
    1.56 +
    1.57 +volatile jint ConcurrentMarkSweepThread::_icms_disabled   = 0;
    1.58 +volatile bool ConcurrentMarkSweepThread::_should_run     = false;
    1.59 +// When icms is enabled, the icms thread is stopped until explicitly
    1.60 +// started.
    1.61 +volatile bool ConcurrentMarkSweepThread::_should_stop    = true;
    1.62 +
    1.63 +SurrogateLockerThread*
    1.64 +     ConcurrentMarkSweepThread::_slt = NULL;
    1.65 +SurrogateLockerThread::SLT_msg_type
    1.66 +     ConcurrentMarkSweepThread::_sltBuffer = SurrogateLockerThread::empty;
    1.67 +Monitor*
    1.68 +     ConcurrentMarkSweepThread::_sltMonitor = NULL;
    1.69 +
    1.70 +ConcurrentMarkSweepThread::ConcurrentMarkSweepThread(CMSCollector* collector)
    1.71 +  : ConcurrentGCThread() {
    1.72 +  assert(UseConcMarkSweepGC,  "UseConcMarkSweepGC should be set");
    1.73 +  assert(_cmst == NULL, "CMS thread already created");
    1.74 +  _cmst = this;
    1.75 +  assert(_collector == NULL, "Collector already set");
    1.76 +  _collector = collector;
    1.77 +
    1.78 +  set_name("Concurrent Mark-Sweep GC Thread");
    1.79 +
    1.80 +  if (os::create_thread(this, os::cgc_thread)) {
    1.81 +    // An old comment here said: "Priority should be just less
    1.82 +    // than that of VMThread".  Since the VMThread runs at
    1.83 +    // NearMaxPriority, the old comment was inaccurate, but
    1.84 +    // changing the default priority to NearMaxPriority-1
    1.85 +    // could change current behavior, so the default of
    1.86 +    // NearMaxPriority stays in place.
    1.87 +    //
    1.88 +    // Note that there's a possibility of the VMThread
    1.89 +    // starving if UseCriticalCMSThreadPriority is on.
    1.90 +    // That won't happen on Solaris for various reasons,
    1.91 +    // but may well happen on non-Solaris platforms.
    1.92 +    int native_prio;
    1.93 +    if (UseCriticalCMSThreadPriority) {
    1.94 +      native_prio = os::java_to_os_priority[CriticalPriority];
    1.95 +    } else {
    1.96 +      native_prio = os::java_to_os_priority[NearMaxPriority];
    1.97 +    }
    1.98 +    os::set_native_priority(this, native_prio);
    1.99 +
   1.100 +    if (!DisableStartThread) {
   1.101 +      os::start_thread(this);
   1.102 +    }
   1.103 +  }
   1.104 +  _sltMonitor = SLT_lock;
   1.105 +  assert(!CMSIncrementalMode || icms_is_enabled(), "Error");
   1.106 +}
   1.107 +
   1.108 +void ConcurrentMarkSweepThread::run() {
   1.109 +  assert(this == cmst(), "just checking");
   1.110 +
   1.111 +  this->record_stack_base_and_size();
   1.112 +  this->initialize_thread_local_storage();
   1.113 +  this->set_active_handles(JNIHandleBlock::allocate_block());
   1.114 +  // From this time Thread::current() should be working.
   1.115 +  assert(this == Thread::current(), "just checking");
   1.116 +  if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) {
   1.117 +    warning("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread);
   1.118 +  }
   1.119 +  // Wait until Universe::is_fully_initialized()
   1.120 +  {
   1.121 +    CMSLoopCountWarn loopX("CMS::run", "waiting for "
   1.122 +                           "Universe::is_fully_initialized()", 2);
   1.123 +    MutexLockerEx x(CGC_lock, true);
   1.124 +    set_CMS_flag(CMS_cms_wants_token);
   1.125 +    // Wait until Universe is initialized and all initialization is completed.
   1.126 +    while (!is_init_completed() && !Universe::is_fully_initialized() &&
   1.127 +           !_should_terminate) {
   1.128 +      CGC_lock->wait(true, 200);
   1.129 +      loopX.tick();
   1.130 +    }
   1.131 +    // Wait until the surrogate locker thread that will do
   1.132 +    // pending list locking on our behalf has been created.
   1.133 +    // We cannot start the SLT thread ourselves since we need
   1.134 +    // to be a JavaThread to do so.
   1.135 +    CMSLoopCountWarn loopY("CMS::run", "waiting for SLT installation", 2);
   1.136 +    while (_slt == NULL && !_should_terminate) {
   1.137 +      CGC_lock->wait(true, 200);
   1.138 +      loopY.tick();
   1.139 +    }
   1.140 +    clear_CMS_flag(CMS_cms_wants_token);
   1.141 +  }
   1.142 +
   1.143 +  while (!_should_terminate) {
   1.144 +    sleepBeforeNextCycle();
   1.145 +    if (_should_terminate) break;
   1.146 +    GCCause::Cause cause = _collector->_full_gc_requested ?
   1.147 +      _collector->_full_gc_cause : GCCause::_cms_concurrent_mark;
   1.148 +    _collector->collect_in_background(false, cause);
   1.149 +  }
   1.150 +  assert(_should_terminate, "just checking");
   1.151 +  // Check that the state of any protocol for synchronization
   1.152 +  // between background (CMS) and foreground collector is "clean"
   1.153 +  // (i.e. will not potentially block the foreground collector,
   1.154 +  // requiring action by us).
   1.155 +  verify_ok_to_terminate();
   1.156 +  // Signal that it is terminated
   1.157 +  {
   1.158 +    MutexLockerEx mu(Terminator_lock,
   1.159 +                     Mutex::_no_safepoint_check_flag);
   1.160 +    assert(_cmst == this, "Weird!");
   1.161 +    _cmst = NULL;
   1.162 +    Terminator_lock->notify();
   1.163 +  }
   1.164 +
   1.165 +  // Thread destructor usually does this..
   1.166 +  ThreadLocalStorage::set_thread(NULL);
   1.167 +}
   1.168 +
   1.169 +#ifndef PRODUCT
   1.170 +void ConcurrentMarkSweepThread::verify_ok_to_terminate() const {
   1.171 +  assert(!(CGC_lock->owned_by_self() || cms_thread_has_cms_token() ||
   1.172 +           cms_thread_wants_cms_token()),
   1.173 +         "Must renounce all worldly possessions and desires for nirvana");
   1.174 +  _collector->verify_ok_to_terminate();
   1.175 +}
   1.176 +#endif
   1.177 +
   1.178 +// create and start a new ConcurrentMarkSweep Thread for given CMS generation
   1.179 +ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::start(CMSCollector* collector) {
   1.180 +  if (!_should_terminate) {
   1.181 +    assert(cmst() == NULL, "start() called twice?");
   1.182 +    ConcurrentMarkSweepThread* th = new ConcurrentMarkSweepThread(collector);
   1.183 +    assert(cmst() == th, "Where did the just-created CMS thread go?");
   1.184 +    return th;
   1.185 +  }
   1.186 +  return NULL;
   1.187 +}
   1.188 +
   1.189 +void ConcurrentMarkSweepThread::stop() {
   1.190 +  if (CMSIncrementalMode) {
   1.191 +    // Disable incremental mode and wake up the thread so it notices the change.
   1.192 +    disable_icms();
   1.193 +    start_icms();
   1.194 +  }
   1.195 +  // it is ok to take late safepoints here, if needed
   1.196 +  {
   1.197 +    MutexLockerEx x(Terminator_lock);
   1.198 +    _should_terminate = true;
   1.199 +  }
   1.200 +  { // Now post a notify on CGC_lock so as to nudge
   1.201 +    // CMS thread(s) that might be slumbering in
   1.202 +    // sleepBeforeNextCycle.
   1.203 +    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
   1.204 +    CGC_lock->notify_all();
   1.205 +  }
   1.206 +  { // Now wait until (all) CMS thread(s) have exited
   1.207 +    MutexLockerEx x(Terminator_lock);
   1.208 +    while(cmst() != NULL) {
   1.209 +      Terminator_lock->wait();
   1.210 +    }
   1.211 +  }
   1.212 +}
   1.213 +
   1.214 +void ConcurrentMarkSweepThread::threads_do(ThreadClosure* tc) {
   1.215 +  assert(tc != NULL, "Null ThreadClosure");
   1.216 +  if (_cmst != NULL) {
   1.217 +    tc->do_thread(_cmst);
   1.218 +  }
   1.219 +  assert(Universe::is_fully_initialized(),
   1.220 +         "Called too early, make sure heap is fully initialized");
   1.221 +  if (_collector != NULL) {
   1.222 +    AbstractWorkGang* gang = _collector->conc_workers();
   1.223 +    if (gang != NULL) {
   1.224 +      gang->threads_do(tc);
   1.225 +    }
   1.226 +  }
   1.227 +}
   1.228 +
   1.229 +void ConcurrentMarkSweepThread::print_on(outputStream* st) const {
   1.230 +  st->print("\"%s\" ", name());
   1.231 +  Thread::print_on(st);
   1.232 +  st->cr();
   1.233 +}
   1.234 +
   1.235 +void ConcurrentMarkSweepThread::print_all_on(outputStream* st) {
   1.236 +  if (_cmst != NULL) {
   1.237 +    _cmst->print_on(st);
   1.238 +    st->cr();
   1.239 +  }
   1.240 +  if (_collector != NULL) {
   1.241 +    AbstractWorkGang* gang = _collector->conc_workers();
   1.242 +    if (gang != NULL) {
   1.243 +      gang->print_worker_threads_on(st);
   1.244 +    }
   1.245 +  }
   1.246 +}
   1.247 +
   1.248 +void ConcurrentMarkSweepThread::synchronize(bool is_cms_thread) {
   1.249 +  assert(UseConcMarkSweepGC, "just checking");
   1.250 +
   1.251 +  MutexLockerEx x(CGC_lock,
   1.252 +                  Mutex::_no_safepoint_check_flag);
   1.253 +  if (!is_cms_thread) {
   1.254 +    assert(Thread::current()->is_VM_thread(), "Not a VM thread");
   1.255 +    CMSSynchronousYieldRequest yr;
   1.256 +    while (CMS_flag_is_set(CMS_cms_has_token)) {
   1.257 +      // indicate that we want to get the token
   1.258 +      set_CMS_flag(CMS_vm_wants_token);
   1.259 +      CGC_lock->wait(true);
   1.260 +    }
   1.261 +    // claim the token and proceed
   1.262 +    clear_CMS_flag(CMS_vm_wants_token);
   1.263 +    set_CMS_flag(CMS_vm_has_token);
   1.264 +  } else {
   1.265 +    assert(Thread::current()->is_ConcurrentGC_thread(),
   1.266 +           "Not a CMS thread");
   1.267 +    // The following barrier assumes there's only one CMS thread.
   1.268 +    // This will need to be modified is there are more CMS threads than one.
   1.269 +    while (CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token)) {
   1.270 +      set_CMS_flag(CMS_cms_wants_token);
   1.271 +      CGC_lock->wait(true);
   1.272 +    }
   1.273 +    // claim the token
   1.274 +    clear_CMS_flag(CMS_cms_wants_token);
   1.275 +    set_CMS_flag(CMS_cms_has_token);
   1.276 +  }
   1.277 +}
   1.278 +
   1.279 +void ConcurrentMarkSweepThread::desynchronize(bool is_cms_thread) {
   1.280 +  assert(UseConcMarkSweepGC, "just checking");
   1.281 +
   1.282 +  MutexLockerEx x(CGC_lock,
   1.283 +                  Mutex::_no_safepoint_check_flag);
   1.284 +  if (!is_cms_thread) {
   1.285 +    assert(Thread::current()->is_VM_thread(), "Not a VM thread");
   1.286 +    assert(CMS_flag_is_set(CMS_vm_has_token), "just checking");
   1.287 +    clear_CMS_flag(CMS_vm_has_token);
   1.288 +    if (CMS_flag_is_set(CMS_cms_wants_token)) {
   1.289 +      // wake-up a waiting CMS thread
   1.290 +      CGC_lock->notify();
   1.291 +    }
   1.292 +    assert(!CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token),
   1.293 +           "Should have been cleared");
   1.294 +  } else {
   1.295 +    assert(Thread::current()->is_ConcurrentGC_thread(),
   1.296 +           "Not a CMS thread");
   1.297 +    assert(CMS_flag_is_set(CMS_cms_has_token), "just checking");
   1.298 +    clear_CMS_flag(CMS_cms_has_token);
   1.299 +    if (CMS_flag_is_set(CMS_vm_wants_token)) {
   1.300 +      // wake-up a waiting VM thread
   1.301 +      CGC_lock->notify();
   1.302 +    }
   1.303 +    assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
   1.304 +           "Should have been cleared");
   1.305 +  }
   1.306 +}
   1.307 +
   1.308 +// Wait until any cms_lock event
   1.309 +void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) {
   1.310 +  MutexLockerEx x(CGC_lock,
   1.311 +                  Mutex::_no_safepoint_check_flag);
   1.312 +  if (_should_terminate || _collector->_full_gc_requested) {
   1.313 +    return;
   1.314 +  }
   1.315 +  set_CMS_flag(CMS_cms_wants_token);   // to provoke notifies
   1.316 +  CGC_lock->wait(Mutex::_no_safepoint_check_flag, t_millis);
   1.317 +  clear_CMS_flag(CMS_cms_wants_token);
   1.318 +  assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
   1.319 +         "Should not be set");
   1.320 +}
   1.321 +
   1.322 +// Wait until the next synchronous GC, a concurrent full gc request,
   1.323 +// or a timeout, whichever is earlier.
   1.324 +void ConcurrentMarkSweepThread::wait_on_cms_lock_for_scavenge(long t_millis) {
   1.325 +  // Wait time in millis or 0 value representing infinite wait for a scavenge
   1.326 +  assert(t_millis >= 0, "Wait time for scavenge should be 0 or positive");
   1.327 +
   1.328 +  GenCollectedHeap* gch = GenCollectedHeap::heap();
   1.329 +  double start_time_secs = os::elapsedTime();
   1.330 +  double end_time_secs = start_time_secs + (t_millis / ((double) MILLIUNITS));
   1.331 +
   1.332 +  // Total collections count before waiting loop
   1.333 +  unsigned int before_count;
   1.334 +  {
   1.335 +    MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
   1.336 +    before_count = gch->total_collections();
   1.337 +  }
   1.338 +
   1.339 +  unsigned int loop_count = 0;
   1.340 +
   1.341 +  while(!_should_terminate) {
   1.342 +    double now_time = os::elapsedTime();
   1.343 +    long wait_time_millis;
   1.344 +
   1.345 +    if(t_millis != 0) {
   1.346 +      // New wait limit
   1.347 +      wait_time_millis = (long) ((end_time_secs - now_time) * MILLIUNITS);
   1.348 +      if(wait_time_millis <= 0) {
   1.349 +        // Wait time is over
   1.350 +        break;
   1.351 +      }
   1.352 +    } else {
   1.353 +      // No wait limit, wait if necessary forever
   1.354 +      wait_time_millis = 0;
   1.355 +    }
   1.356 +
   1.357 +    // Wait until the next event or the remaining timeout
   1.358 +    {
   1.359 +      MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
   1.360 +
   1.361 +      if (_should_terminate || _collector->_full_gc_requested) {
   1.362 +        return;
   1.363 +      }
   1.364 +      set_CMS_flag(CMS_cms_wants_token);   // to provoke notifies
   1.365 +      assert(t_millis == 0 || wait_time_millis > 0, "Sanity");
   1.366 +      CGC_lock->wait(Mutex::_no_safepoint_check_flag, wait_time_millis);
   1.367 +      clear_CMS_flag(CMS_cms_wants_token);
   1.368 +      assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
   1.369 +             "Should not be set");
   1.370 +    }
   1.371 +
   1.372 +    // Extra wait time check before entering the heap lock to get the collection count
   1.373 +    if(t_millis != 0 && os::elapsedTime() >= end_time_secs) {
   1.374 +      // Wait time is over
   1.375 +      break;
   1.376 +    }
   1.377 +
   1.378 +    // Total collections count after the event
   1.379 +    unsigned int after_count;
   1.380 +    {
   1.381 +      MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
   1.382 +      after_count = gch->total_collections();
   1.383 +    }
   1.384 +
   1.385 +    if(before_count != after_count) {
   1.386 +      // There was a collection - success
   1.387 +      break;
   1.388 +    }
   1.389 +
   1.390 +    // Too many loops warning
   1.391 +    if(++loop_count == 0) {
   1.392 +      warning("wait_on_cms_lock_for_scavenge() has looped %u times", loop_count - 1);
   1.393 +    }
   1.394 +  }
   1.395 +}
   1.396 +
   1.397 +void ConcurrentMarkSweepThread::sleepBeforeNextCycle() {
   1.398 +  while (!_should_terminate) {
   1.399 +    if (CMSIncrementalMode) {
   1.400 +      icms_wait();
   1.401 +      if(CMSWaitDuration >= 0) {
   1.402 +        // Wait until the next synchronous GC, a concurrent full gc
   1.403 +        // request or a timeout, whichever is earlier.
   1.404 +        wait_on_cms_lock_for_scavenge(CMSWaitDuration);
   1.405 +      }
   1.406 +      return;
   1.407 +    } else {
   1.408 +      if(CMSWaitDuration >= 0) {
   1.409 +        // Wait until the next synchronous GC, a concurrent full gc
   1.410 +        // request or a timeout, whichever is earlier.
   1.411 +        wait_on_cms_lock_for_scavenge(CMSWaitDuration);
   1.412 +      } else {
   1.413 +        // Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently
   1.414 +        wait_on_cms_lock(CMSCheckInterval);
   1.415 +      }
   1.416 +    }
   1.417 +    // Check if we should start a CMS collection cycle
   1.418 +    if (_collector->shouldConcurrentCollect()) {
   1.419 +      return;
   1.420 +    }
   1.421 +    // .. collection criterion not yet met, let's go back
   1.422 +    // and wait some more
   1.423 +  }
   1.424 +}
   1.425 +
   1.426 +// Incremental CMS
   1.427 +void ConcurrentMarkSweepThread::start_icms() {
   1.428 +  assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking");
   1.429 +  MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag);
   1.430 +  trace_state("start_icms");
   1.431 +  _should_run = true;
   1.432 +  iCMS_lock->notify_all();
   1.433 +}
   1.434 +
   1.435 +void ConcurrentMarkSweepThread::stop_icms() {
   1.436 +  assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking");
   1.437 +  MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag);
   1.438 +  if (!_should_stop) {
   1.439 +    trace_state("stop_icms");
   1.440 +    _should_stop = true;
   1.441 +    _should_run = false;
   1.442 +    asynchronous_yield_request();
   1.443 +    iCMS_lock->notify_all();
   1.444 +  }
   1.445 +}
   1.446 +
   1.447 +void ConcurrentMarkSweepThread::icms_wait() {
   1.448 +  assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking");
   1.449 +  if (_should_stop && icms_is_enabled()) {
   1.450 +    MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag);
   1.451 +    trace_state("pause_icms");
   1.452 +    _collector->stats().stop_cms_timer();
   1.453 +    while(!_should_run && icms_is_enabled()) {
   1.454 +      iCMS_lock->wait(Mutex::_no_safepoint_check_flag);
   1.455 +    }
   1.456 +    _collector->stats().start_cms_timer();
   1.457 +    _should_stop = false;
   1.458 +    trace_state("pause_icms end");
   1.459 +  }
   1.460 +}
   1.461 +
   1.462 +// Note: this method, although exported by the ConcurrentMarkSweepThread,
   1.463 +// which is a non-JavaThread, can only be called by a JavaThread.
   1.464 +// Currently this is done at vm creation time (post-vm-init) by the
   1.465 +// main/Primordial (Java)Thread.
   1.466 +// XXX Consider changing this in the future to allow the CMS thread
   1.467 +// itself to create this thread?
   1.468 +void ConcurrentMarkSweepThread::makeSurrogateLockerThread(TRAPS) {
   1.469 +  assert(UseConcMarkSweepGC, "SLT thread needed only for CMS GC");
   1.470 +  assert(_slt == NULL, "SLT already created");
   1.471 +  _slt = SurrogateLockerThread::make(THREAD);
   1.472 +}

mercurial