8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 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 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
26
27 #include "classfile/classLoaderDataGraph.hpp"
28 #include "gc/shared/oopStorageParState.inline.hpp"
29 #include "gc/shenandoah/shenandoahHeuristics.hpp"
30 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
31 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
32 #include "gc/shenandoah/shenandoahUtils.hpp"
33 #include "memory/resourceArea.hpp"
34
35 template <bool CONCURRENT>
36 ShenandoahJNIHandleRoots<CONCURRENT>::ShenandoahJNIHandleRoots() :
37 _claimed(false),
38 _itr(JNIHandles::global_handles()) {
39 }
40
41 template <bool CONCURRENT>
42 template <typename T>
43 void ShenandoahJNIHandleRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) {
44 if (CONCURRENT) {
45 _itr.oops_do(cl);
46 } else {
47 if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
48 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
49 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
50 _itr.oops_do(cl);
51 }
52 }
53 }
54
55 template <typename IsAlive, typename KeepAlive>
56 void ShenandoahWeakRoots::oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id) {
57 _task.work<IsAlive, KeepAlive>(worker_id, is_alive, keep_alive);
58 }
59
60 template <typename ITR>
61 ShenandoahCodeCacheRoots<ITR>::ShenandoahCodeCacheRoots() {
62 nmethod::oops_do_marking_prologue();
63 }
64
65 template <typename ITR>
66 void ShenandoahCodeCacheRoots<ITR>::code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id) {
67 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
68 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
69 _coderoots_iterator.possibly_parallel_blobs_do(blob_cl);
70 }
71
72 template <typename ITR>
73 ShenandoahCodeCacheRoots<ITR>::~ShenandoahCodeCacheRoots() {
74 nmethod::oops_do_marking_epilogue();
75 }
76
77 class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
78 private:
79 OopClosure* _f;
171 _cld_roots.clds_do(clds, NULL, worker_id);
172 _thread_roots.threads_do(&tc_cl, worker_id);
173 }
174
175 template <typename IsAlive, typename KeepAlive>
176 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
177 CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
178 CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
179 CLDToOopClosure* weak_clds = ShenandoahHeap::heap()->unload_classes() ? NULL : &clds;
180
181 _serial_roots.oops_do(keep_alive, worker_id);
182 _jni_roots.oops_do(keep_alive, worker_id);
183
184 _thread_roots.oops_do(keep_alive, NULL, worker_id);
185 _cld_roots.clds_do(&clds, weak_clds, worker_id);
186
187 if(_update_code_cache) {
188 _code_roots.code_blobs_do(&update_blobs, worker_id);
189 }
190
191 _weak_roots.oops_do<IsAlive, KeepAlive>(is_alive, keep_alive, worker_id);
192 _dedup_roots.oops_do(is_alive, keep_alive, worker_id);
193 }
194
195 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
|
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 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 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
26
27 #include "classfile/classLoaderDataGraph.hpp"
28 #include "classfile/stringTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "gc/shared/oopStorageParState.inline.hpp"
31 #include "gc/shenandoah/shenandoahHeuristics.hpp"
32 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
33 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
34 #include "gc/shenandoah/shenandoahUtils.hpp"
35 #include "prims/resolvedMethodTable.hpp"
36 #include "memory/resourceArea.hpp"
37
38 template <bool CONCURRENT>
39 inline ShenandoahWeakRoot<CONCURRENT>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
40 _itr(storage), _phase(phase) {
41 }
42
43 template <bool CONCURRENT>
44 template <typename Closure>
45 inline void ShenandoahWeakRoot<CONCURRENT>::oops_do(Closure* cl, uint worker_id) {
46 if (CONCURRENT) {
47 _itr.oops_do(cl);
48 } else {
49 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
50 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id);
51 _itr.oops_do(cl);
52 }
53 }
54
55 inline ShenandoahWeakRoot<false>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
56 _itr(storage), _phase(phase) {
57 }
58
59 template <typename IsAliveClosure, typename KeepAliveClosure>
60 void ShenandoahWeakRoot<false /* concurrent */>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
61 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
62 ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
63 _itr.weak_oops_do(is_alive, keep_alive);
64 }
65
66 template <bool CONCURRENT>
67 ShenandoahWeakRoots<CONCURRENT>::ShenandoahWeakRoots() :
68 _jni_roots(JNIHandles::weak_global_handles(), ShenandoahPhaseTimings::JNIWeakRoots),
69 _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
70 _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
71 _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
72 }
73
74 template <bool CONCURRENT>
75 template <typename Closure>
76 void ShenandoahWeakRoots<CONCURRENT>::oops_do(Closure* cl, uint worker_id) {
77 _jni_roots.oops_do(cl, worker_id);
78 _string_table_roots.oops_do(cl, worker_id);
79 _resolved_method_table_roots.oops_do(cl, worker_id);
80 _vm_roots.oops_do(cl, worker_id);
81 }
82
83 inline ShenandoahWeakRoots<false /* concurrent */>::ShenandoahWeakRoots() :
84 _jni_roots(JNIHandles::weak_global_handles(), ShenandoahPhaseTimings::JNIWeakRoots),
85 _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
86 _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
87 _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
88 }
89
90 template <typename IsAliveClosure, typename KeepAliveClosure>
91 void ShenandoahWeakRoots<false /* concurrent*/>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
92 _jni_roots.weak_oops_do(is_alive, keep_alive, worker_id);
93 _string_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
94 _resolved_method_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
95 _vm_roots.weak_oops_do(is_alive, keep_alive, worker_id);
96 }
97
98 template <typename Closure>
99 void ShenandoahWeakRoots<false /* concurrent */>::oops_do(Closure* cl, uint worker_id) {
100 AlwaysTrueClosure always_true;
101 weak_oops_do<AlwaysTrueClosure, Closure>(&always_true, cl, worker_id);
102 }
103
104 template <bool CONCURRENT>
105 ShenandoahJNIHandleRoots<CONCURRENT>::ShenandoahJNIHandleRoots() :
106 _claimed(false),
107 _itr(JNIHandles::global_handles()) {
108 }
109
110 template <bool CONCURRENT>
111 template <typename T>
112 void ShenandoahJNIHandleRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) {
113 if (CONCURRENT) {
114 _itr.oops_do(cl);
115 } else {
116 if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
117 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
118 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
119 _itr.oops_do(cl);
120 }
121 }
122 }
123
124 template <typename ITR>
125 ShenandoahCodeCacheRoots<ITR>::ShenandoahCodeCacheRoots() {
126 nmethod::oops_do_marking_prologue();
127 }
128
129 template <typename ITR>
130 void ShenandoahCodeCacheRoots<ITR>::code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id) {
131 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
132 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
133 _coderoots_iterator.possibly_parallel_blobs_do(blob_cl);
134 }
135
136 template <typename ITR>
137 ShenandoahCodeCacheRoots<ITR>::~ShenandoahCodeCacheRoots() {
138 nmethod::oops_do_marking_epilogue();
139 }
140
141 class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
142 private:
143 OopClosure* _f;
235 _cld_roots.clds_do(clds, NULL, worker_id);
236 _thread_roots.threads_do(&tc_cl, worker_id);
237 }
238
239 template <typename IsAlive, typename KeepAlive>
240 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
241 CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
242 CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
243 CLDToOopClosure* weak_clds = ShenandoahHeap::heap()->unload_classes() ? NULL : &clds;
244
245 _serial_roots.oops_do(keep_alive, worker_id);
246 _jni_roots.oops_do(keep_alive, worker_id);
247
248 _thread_roots.oops_do(keep_alive, NULL, worker_id);
249 _cld_roots.clds_do(&clds, weak_clds, worker_id);
250
251 if(_update_code_cache) {
252 _code_roots.code_blobs_do(&update_blobs, worker_id);
253 }
254
255 _serial_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
256 _weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
257 _dedup_roots.oops_do(is_alive, keep_alive, worker_id);
258 }
259
260 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
|