Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp
38921 views
1
/*
2
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
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
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "classfile/systemDictionary.hpp"
27
#include "gc_implementation/shared/concurrentGCThread.hpp"
28
#include "oops/instanceRefKlass.hpp"
29
#include "oops/oop.inline.hpp"
30
#include "runtime/init.hpp"
31
#include "runtime/interfaceSupport.hpp"
32
#include "runtime/java.hpp"
33
#include "runtime/javaCalls.hpp"
34
35
// CopyrightVersion 1.2
36
37
int ConcurrentGCThread::_CGC_flag = CGC_nil;
38
39
ConcurrentGCThread::ConcurrentGCThread() :
40
_should_terminate(false), _has_terminated(false) {
41
};
42
43
void ConcurrentGCThread::create_and_start() {
44
if (os::create_thread(this, os::cgc_thread)) {
45
// XXX: need to set this to low priority
46
// unless "agressive mode" set; priority
47
// should be just less than that of VMThread.
48
os::set_priority(this, NearMaxPriority);
49
if (!_should_terminate && !DisableStartThread) {
50
os::start_thread(this);
51
}
52
}
53
}
54
55
void ConcurrentGCThread::initialize_in_thread() {
56
this->record_stack_base_and_size();
57
this->initialize_thread_local_storage();
58
this->set_active_handles(JNIHandleBlock::allocate_block());
59
// From this time Thread::current() should be working.
60
assert(this == Thread::current(), "just checking");
61
}
62
63
void ConcurrentGCThread::wait_for_universe_init() {
64
MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
65
while (!is_init_completed() && !_should_terminate) {
66
CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200);
67
}
68
}
69
70
void ConcurrentGCThread::terminate() {
71
// Signal that it is terminated
72
{
73
MutexLockerEx mu(Terminator_lock,
74
Mutex::_no_safepoint_check_flag);
75
_has_terminated = true;
76
Terminator_lock->notify();
77
}
78
79
// Thread destructor usually does this..
80
ThreadLocalStorage::set_thread(NULL);
81
}
82
83
static void _sltLoop(JavaThread* thread, TRAPS) {
84
SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
85
slt->loop();
86
}
87
88
SurrogateLockerThread::SurrogateLockerThread() :
89
JavaThread(&_sltLoop),
90
_monitor(Mutex::nonleaf, "SLTMonitor"),
91
_buffer(empty)
92
{}
93
94
SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
95
Klass* k =
96
SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
97
true, CHECK_NULL);
98
instanceKlassHandle klass (THREAD, k);
99
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
100
101
const char thread_name[] = "Surrogate Locker Thread (Concurrent GC)";
102
Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);
103
104
// Initialize thread_oop to put it into the system threadGroup
105
Handle thread_group (THREAD, Universe::system_thread_group());
106
JavaValue result(T_VOID);
107
JavaCalls::call_special(&result, thread_oop,
108
klass,
109
vmSymbols::object_initializer_name(),
110
vmSymbols::threadgroup_string_void_signature(),
111
thread_group,
112
string,
113
CHECK_NULL);
114
115
SurrogateLockerThread* res;
116
{
117
MutexLocker mu(Threads_lock);
118
res = new SurrogateLockerThread();
119
120
// At this point it may be possible that no osthread was created for the
121
// JavaThread due to lack of memory. We would have to throw an exception
122
// in that case. However, since this must work and we do not allow
123
// exceptions anyway, check and abort if this fails.
124
if (res == NULL || res->osthread() == NULL) {
125
vm_exit_during_initialization("java.lang.OutOfMemoryError",
126
"unable to create new native thread");
127
}
128
java_lang_Thread::set_thread(thread_oop(), res);
129
java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
130
java_lang_Thread::set_daemon(thread_oop());
131
132
res->set_threadObj(thread_oop());
133
Threads::add(res);
134
Thread::start(res);
135
}
136
os::yield(); // This seems to help with initial start-up of SLT
137
return res;
138
}
139
140
void SurrogateLockerThread::report_missing_slt() {
141
vm_exit_during_initialization(
142
"GC before GC support fully initialized: "
143
"SLT is needed but has not yet been created.");
144
ShouldNotReachHere();
145
}
146
147
void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
148
MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
149
assert(_buffer == empty, "Should be empty");
150
assert(msg != empty, "empty message");
151
assert(!Heap_lock->owned_by_self(), "Heap_lock owned by requesting thread");
152
153
_buffer = msg;
154
while (_buffer != empty) {
155
_monitor.notify();
156
_monitor.wait(Mutex::_no_safepoint_check_flag);
157
}
158
}
159
160
// ======= Surrogate Locker Thread =============
161
162
void SurrogateLockerThread::loop() {
163
BasicLock pll_basic_lock;
164
SLT_msg_type msg;
165
debug_only(unsigned int owned = 0;)
166
167
while (/* !isTerminated() */ 1) {
168
{
169
MutexLocker x(&_monitor);
170
// Since we are a JavaThread, we can't be here at a safepoint.
171
assert(!SafepointSynchronize::is_at_safepoint(),
172
"SLT is a JavaThread");
173
// wait for msg buffer to become non-empty
174
while (_buffer == empty) {
175
_monitor.notify();
176
_monitor.wait();
177
}
178
msg = _buffer;
179
}
180
switch(msg) {
181
case acquirePLL: {
182
InstanceRefKlass::acquire_pending_list_lock(&pll_basic_lock);
183
debug_only(owned++;)
184
break;
185
}
186
case releaseAndNotifyPLL: {
187
assert(owned > 0, "Don't have PLL");
188
InstanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock);
189
debug_only(owned--;)
190
break;
191
}
192
case empty:
193
default: {
194
guarantee(false,"Unexpected message in _buffer");
195
break;
196
}
197
}
198
{
199
MutexLocker x(&_monitor);
200
// Since we are a JavaThread, we can't be here at a safepoint.
201
assert(!SafepointSynchronize::is_at_safepoint(),
202
"SLT is a JavaThread");
203
_buffer = empty;
204
_monitor.notify();
205
}
206
}
207
assert(!_monitor.owned_by_self(), "Should unlock before exit.");
208
}
209
210