Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/shared/concurrentGCThread.cpp @ 20278:2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
Reviewed-by: tschatzl, ehelin, brutisso, coleenp, roland, iveresov
Contributed-by: stefan.karlsson@oracle.com, mikael.gerdin@oracle.com
author | stefank |
---|---|
date | Mon, 07 Jul 2014 10:12:40 +0200 |
parents | 581e70386ec9 |
children | 4e4ebe50c8e3 |
rev | line source |
---|---|
342 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4022
diff
changeset
|
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. |
342 | 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:
844
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
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:
844
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
1972 | 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" | |
342 | 34 |
1972 | 35 // CopyrightVersion 1.2 |
342 | 36 |
37 int ConcurrentGCThread::_CGC_flag = CGC_nil; | |
38 | |
794 | 39 ConcurrentGCThread::ConcurrentGCThread() : |
40 _should_terminate(false), _has_terminated(false) { | |
342 | 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) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4022
diff
changeset
|
95 Klass* k = |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
96 SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), |
342 | 97 true, CHECK_NULL); |
98 instanceKlassHandle klass (THREAD, k); | |
99 instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL); | |
100 | |
1842
6e0aac35bfa9
6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents:
1552
diff
changeset
|
101 const char thread_name[] = "Surrogate Locker Thread (Concurrent GC)"; |
342 | 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, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
109 vmSymbols::object_initializer_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
110 vmSymbols::threadgroup_string_void_signature(), |
342 | 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::manipulatePLL(SLT_msg_type msg) { | |
141 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag); | |
142 assert(_buffer == empty, "Should be empty"); | |
143 assert(msg != empty, "empty message"); | |
4022
db89aa49298f
7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents:
3767
diff
changeset
|
144 assert(!Heap_lock->owned_by_self(), "Heap_lock owned by requesting thread"); |
db89aa49298f
7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents:
3767
diff
changeset
|
145 |
342 | 146 _buffer = msg; |
147 while (_buffer != empty) { | |
148 _monitor.notify(); | |
149 _monitor.wait(Mutex::_no_safepoint_check_flag); | |
150 } | |
151 } | |
152 | |
153 // ======= Surrogate Locker Thread ============= | |
154 | |
155 void SurrogateLockerThread::loop() { | |
156 BasicLock pll_basic_lock; | |
157 SLT_msg_type msg; | |
158 debug_only(unsigned int owned = 0;) | |
159 | |
160 while (/* !isTerminated() */ 1) { | |
161 { | |
162 MutexLocker x(&_monitor); | |
163 // Since we are a JavaThread, we can't be here at a safepoint. | |
164 assert(!SafepointSynchronize::is_at_safepoint(), | |
165 "SLT is a JavaThread"); | |
166 // wait for msg buffer to become non-empty | |
167 while (_buffer == empty) { | |
168 _monitor.notify(); | |
169 _monitor.wait(); | |
170 } | |
171 msg = _buffer; | |
172 } | |
173 switch(msg) { | |
174 case acquirePLL: { | |
6735
aed758eda82a
7195833: NPG: Rename instanceClassLoaderKlass, instanceRefKlass and instanceMirrorKlass
coleenp
parents:
6725
diff
changeset
|
175 InstanceRefKlass::acquire_pending_list_lock(&pll_basic_lock); |
342 | 176 debug_only(owned++;) |
177 break; | |
178 } | |
179 case releaseAndNotifyPLL: { | |
180 assert(owned > 0, "Don't have PLL"); | |
6735
aed758eda82a
7195833: NPG: Rename instanceClassLoaderKlass, instanceRefKlass and instanceMirrorKlass
coleenp
parents:
6725
diff
changeset
|
181 InstanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock); |
342 | 182 debug_only(owned--;) |
183 break; | |
184 } | |
185 case empty: | |
186 default: { | |
187 guarantee(false,"Unexpected message in _buffer"); | |
188 break; | |
189 } | |
190 } | |
191 { | |
192 MutexLocker x(&_monitor); | |
193 // Since we are a JavaThread, we can't be here at a safepoint. | |
194 assert(!SafepointSynchronize::is_at_safepoint(), | |
195 "SLT is a JavaThread"); | |
196 _buffer = empty; | |
197 _monitor.notify(); | |
198 } | |
199 } | |
200 assert(!_monitor.owned_by_self(), "Should unlock before exit."); | |
201 } |