Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp
38921 views
/*1* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "classfile/systemDictionary.hpp"26#include "gc_implementation/shared/concurrentGCThread.hpp"27#include "oops/instanceRefKlass.hpp"28#include "oops/oop.inline.hpp"29#include "runtime/init.hpp"30#include "runtime/interfaceSupport.hpp"31#include "runtime/java.hpp"32#include "runtime/javaCalls.hpp"3334// CopyrightVersion 1.23536int ConcurrentGCThread::_CGC_flag = CGC_nil;3738ConcurrentGCThread::ConcurrentGCThread() :39_should_terminate(false), _has_terminated(false) {40};4142void ConcurrentGCThread::create_and_start() {43if (os::create_thread(this, os::cgc_thread)) {44// XXX: need to set this to low priority45// unless "agressive mode" set; priority46// should be just less than that of VMThread.47os::set_priority(this, NearMaxPriority);48if (!_should_terminate && !DisableStartThread) {49os::start_thread(this);50}51}52}5354void ConcurrentGCThread::initialize_in_thread() {55this->record_stack_base_and_size();56this->initialize_thread_local_storage();57this->set_active_handles(JNIHandleBlock::allocate_block());58// From this time Thread::current() should be working.59assert(this == Thread::current(), "just checking");60}6162void ConcurrentGCThread::wait_for_universe_init() {63MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);64while (!is_init_completed() && !_should_terminate) {65CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200);66}67}6869void ConcurrentGCThread::terminate() {70// Signal that it is terminated71{72MutexLockerEx mu(Terminator_lock,73Mutex::_no_safepoint_check_flag);74_has_terminated = true;75Terminator_lock->notify();76}7778// Thread destructor usually does this..79ThreadLocalStorage::set_thread(NULL);80}8182static void _sltLoop(JavaThread* thread, TRAPS) {83SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;84slt->loop();85}8687SurrogateLockerThread::SurrogateLockerThread() :88JavaThread(&_sltLoop),89_monitor(Mutex::nonleaf, "SLTMonitor"),90_buffer(empty)91{}9293SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {94Klass* k =95SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),96true, CHECK_NULL);97instanceKlassHandle klass (THREAD, k);98instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);99100const char thread_name[] = "Surrogate Locker Thread (Concurrent GC)";101Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);102103// Initialize thread_oop to put it into the system threadGroup104Handle thread_group (THREAD, Universe::system_thread_group());105JavaValue result(T_VOID);106JavaCalls::call_special(&result, thread_oop,107klass,108vmSymbols::object_initializer_name(),109vmSymbols::threadgroup_string_void_signature(),110thread_group,111string,112CHECK_NULL);113114SurrogateLockerThread* res;115{116MutexLocker mu(Threads_lock);117res = new SurrogateLockerThread();118119// At this point it may be possible that no osthread was created for the120// JavaThread due to lack of memory. We would have to throw an exception121// in that case. However, since this must work and we do not allow122// exceptions anyway, check and abort if this fails.123if (res == NULL || res->osthread() == NULL) {124vm_exit_during_initialization("java.lang.OutOfMemoryError",125"unable to create new native thread");126}127java_lang_Thread::set_thread(thread_oop(), res);128java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);129java_lang_Thread::set_daemon(thread_oop());130131res->set_threadObj(thread_oop());132Threads::add(res);133Thread::start(res);134}135os::yield(); // This seems to help with initial start-up of SLT136return res;137}138139void SurrogateLockerThread::report_missing_slt() {140vm_exit_during_initialization(141"GC before GC support fully initialized: "142"SLT is needed but has not yet been created.");143ShouldNotReachHere();144}145146void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {147MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);148assert(_buffer == empty, "Should be empty");149assert(msg != empty, "empty message");150assert(!Heap_lock->owned_by_self(), "Heap_lock owned by requesting thread");151152_buffer = msg;153while (_buffer != empty) {154_monitor.notify();155_monitor.wait(Mutex::_no_safepoint_check_flag);156}157}158159// ======= Surrogate Locker Thread =============160161void SurrogateLockerThread::loop() {162BasicLock pll_basic_lock;163SLT_msg_type msg;164debug_only(unsigned int owned = 0;)165166while (/* !isTerminated() */ 1) {167{168MutexLocker x(&_monitor);169// Since we are a JavaThread, we can't be here at a safepoint.170assert(!SafepointSynchronize::is_at_safepoint(),171"SLT is a JavaThread");172// wait for msg buffer to become non-empty173while (_buffer == empty) {174_monitor.notify();175_monitor.wait();176}177msg = _buffer;178}179switch(msg) {180case acquirePLL: {181InstanceRefKlass::acquire_pending_list_lock(&pll_basic_lock);182debug_only(owned++;)183break;184}185case releaseAndNotifyPLL: {186assert(owned > 0, "Don't have PLL");187InstanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock);188debug_only(owned--;)189break;190}191case empty:192default: {193guarantee(false,"Unexpected message in _buffer");194break;195}196}197{198MutexLocker x(&_monitor);199// Since we are a JavaThread, we can't be here at a safepoint.200assert(!SafepointSynchronize::is_at_safepoint(),201"SLT is a JavaThread");202_buffer = empty;203_monitor.notify();204}205}206assert(!_monitor.owned_by_self(), "Should unlock before exit.");207}208209210