1 /*
2 * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.
7 *
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 */
24 #include "precompiled.hpp"
25
26 #include "classfile/classLoaderDataGraph.hpp"
27 #include "classfile/stringTable.hpp"
28 #include "classfile/systemDictionary.hpp"
29 #include "code/codeCache.hpp"
30 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
31 #include "gc/shenandoah/shenandoahHeap.hpp"
32 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
33 #include "gc/shenandoah/shenandoahStringDedup.hpp"
34 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
35 #include "gc/shenandoah/shenandoahUtils.hpp"
36 #include "gc/shenandoah/shenandoahVMOperations.hpp"
37 #include "gc/shared/weakProcessor.inline.hpp"
38 #include "memory/allocation.inline.hpp"
39 #include "memory/iterator.hpp"
40 #include "memory/resourceArea.hpp"
41 #include "runtime/thread.hpp"
42 #include "services/management.hpp"
43
44 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
45 ShenandoahPhaseTimings::Phase phase) :
46 _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
47 _srs(n_workers),
48 _par_state_string(StringTable::weak_storage()),
49 _phase(phase),
50 _coderoots_all_iterator(ShenandoahCodeRoots::iterator()),
51 _weak_processor_task(n_workers)
52 {
53 heap->phase_timings()->record_workers_start(_phase);
54
55 if (ShenandoahStringDedup::is_enabled()) {
56 StringDedup::gc_prologue(false);
57 }
58 }
59
60 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
61 delete _process_strong_tasks;
62 if (ShenandoahStringDedup::is_enabled()) {
63 StringDedup::gc_epilogue();
64 }
65
66 ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
67 }
68
69 void ShenandoahRootProcessor::process_all_roots_slow(OopClosure* oops) {
70 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
71 CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
72
73 CodeCache::blobs_do(&blobs);
74 ClassLoaderDataGraph::cld_do(&clds);
75 Universe::oops_do(oops);
76 Management::oops_do(oops);
77 JvmtiExport::oops_do(oops);
78 JNIHandles::oops_do(oops);
79 WeakProcessor::oops_do(oops);
80 ObjectSynchronizer::oops_do(oops);
81 SystemDictionary::oops_do(oops);
82
83 if (ShenandoahStringDedup::is_enabled()) {
84 ShenandoahStringDedup::oops_do_slow(oops);
85 }
86
87 // Do thread roots the last. This allows verification code to find
88 // any broken objects from those special roots first, not the accidental
176 Universe::oops_do(strong_roots);
177 }
178
179 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
180 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
181 JNIHandles::oops_do(strong_roots);
182 }
183 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_Management_oops_do)) {
184 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ManagementRoots, worker_id);
185 Management::oops_do(strong_roots);
186 }
187 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_jvmti_oops_do)) {
188 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JVMTIRoots, worker_id);
189 JvmtiExport::oops_do(strong_roots);
190 }
191 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) {
192 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id);
193 SystemDictionary::oops_do(strong_roots);
194 }
195 if (jni_weak_roots != NULL) {
196 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIWeakRoots, worker_id);
197 AlwaysTrueClosure always_true;
198 _weak_processor_task.work<AlwaysTrueClosure, OopClosure>(worker_id, &always_true, jni_weak_roots);
199 }
200
201 if (ShenandoahStringDedup::is_enabled() && weak_roots != NULL) {
202 ShenandoahStringDedup::parallel_oops_do(weak_roots, worker_id);
203 }
204
205 {
206 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id);
207 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_ObjectSynchronizer_oops_do)) {
208 ObjectSynchronizer::oops_do(strong_roots);
209 }
210 }
211 }
212
213 uint ShenandoahRootProcessor::n_workers() const {
214 return _srs.n_threads();
215 }
216
217 ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_workers, ShenandoahPhaseTimings::Phase phase) :
218 _evacuation_tasks(new SubTasksDone(SHENANDOAH_EVAC_NumElements)),
|
1 /*
2 * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.
7 *
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 */
24 #include "precompiled.hpp"
25
26 #include "classfile/classLoaderDataGraph.hpp"
27 #include "classfile/stringTable.hpp"
28 #include "classfile/systemDictionary.hpp"
29 #include "code/codeCache.hpp"
30 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
31 #include "gc/shenandoah/shenandoahHeap.hpp"
32 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
33 #include "gc/shenandoah/shenandoahStringDedup.hpp"
34 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
35 #include "gc/shenandoah/shenandoahUtils.hpp"
36 #include "gc/shenandoah/shenandoahVMOperations.hpp"
37 #include "gc/shared/weakProcessor.inline.hpp"
38 #include "memory/allocation.inline.hpp"
39 #include "memory/iterator.hpp"
40 #include "memory/resourceArea.hpp"
41 #include "runtime/thread.hpp"
42 #include "services/management.hpp"
43
44 struct PhaseMap {
45 WeakProcessorPhases::Phase _weak_processor_phase;
46 ShenandoahPhaseTimings::GCParPhases _shenandoah_phase;
47 };
48
49 static const struct PhaseMap phase_mapping[] = {
50 #if INCLUDE_JVMTI
51 {WeakProcessorPhases::jvmti, ShenandoahPhaseTimings::JVMTIWeakRoots},
52 #endif
53 #if INCLUDE_JFR
54 {WeakProcessorPhases::jfr, ShenandoahPhaseTimings::JFRWeakRoots},
55 #endif
56 {WeakProcessorPhases::jni, ShenandoahPhaseTimings::JNIWeakRoots},
57 {WeakProcessorPhases::stringtable, ShenandoahPhaseTimings::StringTableRoots},
58 {WeakProcessorPhases::vm, ShenandoahPhaseTimings::VMWeakRoots}
59 };
60
61 STATIC_ASSERT(sizeof(phase_mapping) / sizeof(PhaseMap) == WeakProcessorPhases::phase_count);
62
63 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
64 ShenandoahPhaseTimings::Phase phase) :
65 _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
66 _srs(n_workers),
67 _par_state_string(StringTable::weak_storage()),
68 _phase(phase),
69 _coderoots_all_iterator(ShenandoahCodeRoots::iterator()),
70 _weak_processor_timings(n_workers),
71 _weak_processor_task(&_weak_processor_timings, n_workers),
72 _processed_weak_roots(false) {
73 heap->phase_timings()->record_workers_start(_phase);
74
75 if (ShenandoahStringDedup::is_enabled()) {
76 StringDedup::gc_prologue(false);
77 }
78 }
79
80 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
81 delete _process_strong_tasks;
82 if (ShenandoahStringDedup::is_enabled()) {
83 StringDedup::gc_epilogue();
84 }
85
86 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
87
88 if (_processed_weak_roots) {
89 assert(_weak_processor_timings.max_threads() == n_workers(), "Must match");
90 for (uint index = 0; index < WeakProcessorPhases::phase_count; index ++) {
91 weak_processor_timing_to_shenandoah_timing(phase_mapping[index]._weak_processor_phase,
92 phase_mapping[index]._shenandoah_phase,
93 worker_times);
94 }
95 }
96
97 ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
98 }
99
100 void ShenandoahRootProcessor::weak_processor_timing_to_shenandoah_timing(const WeakProcessorPhases::Phase wpp,
101 const ShenandoahPhaseTimings::GCParPhases spp,
102 ShenandoahWorkerTimings* worker_times) const {
103 if (WeakProcessorPhases::is_serial(wpp)) {
104 worker_times->record_time_secs(spp, 0, _weak_processor_timings.phase_time_sec(wpp));
105 } else {
106 for (uint index = 0; index < _weak_processor_timings.max_threads(); index ++) {
107 worker_times->record_time_secs(spp, index, _weak_processor_timings.worker_time_sec(index, wpp));
108 }
109 }
110 }
111
112 void ShenandoahRootProcessor::process_all_roots_slow(OopClosure* oops) {
113 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
114 CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
115
116 CodeCache::blobs_do(&blobs);
117 ClassLoaderDataGraph::cld_do(&clds);
118 Universe::oops_do(oops);
119 Management::oops_do(oops);
120 JvmtiExport::oops_do(oops);
121 JNIHandles::oops_do(oops);
122 WeakProcessor::oops_do(oops);
123 ObjectSynchronizer::oops_do(oops);
124 SystemDictionary::oops_do(oops);
125
126 if (ShenandoahStringDedup::is_enabled()) {
127 ShenandoahStringDedup::oops_do_slow(oops);
128 }
129
130 // Do thread roots the last. This allows verification code to find
131 // any broken objects from those special roots first, not the accidental
219 Universe::oops_do(strong_roots);
220 }
221
222 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
223 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
224 JNIHandles::oops_do(strong_roots);
225 }
226 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_Management_oops_do)) {
227 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ManagementRoots, worker_id);
228 Management::oops_do(strong_roots);
229 }
230 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_jvmti_oops_do)) {
231 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JVMTIRoots, worker_id);
232 JvmtiExport::oops_do(strong_roots);
233 }
234 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) {
235 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id);
236 SystemDictionary::oops_do(strong_roots);
237 }
238 if (jni_weak_roots != NULL) {
239 AlwaysTrueClosure always_true;
240 _weak_processor_task.work<AlwaysTrueClosure, OopClosure>(worker_id, &always_true, jni_weak_roots);
241 _processed_weak_roots = true;
242 }
243
244 if (ShenandoahStringDedup::is_enabled() && weak_roots != NULL) {
245 ShenandoahStringDedup::parallel_oops_do(weak_roots, worker_id);
246 }
247
248 {
249 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id);
250 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_ObjectSynchronizer_oops_do)) {
251 ObjectSynchronizer::oops_do(strong_roots);
252 }
253 }
254 }
255
256 uint ShenandoahRootProcessor::n_workers() const {
257 return _srs.n_threads();
258 }
259
260 ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_workers, ShenandoahPhaseTimings::Phase phase) :
261 _evacuation_tasks(new SubTasksDone(SHENANDOAH_EVAC_NumElements)),
|