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 StringTable::oops_do(oops);
83
84 if (ShenandoahStringDedup::is_enabled()) {
85 ShenandoahStringDedup::oops_do_slow(oops);
86 }
87
88 // Do thread roots the last. This allows verification code to find
177 Universe::oops_do(strong_roots);
178 }
179
180 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
181 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
182 JNIHandles::oops_do(strong_roots);
183 }
184 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_Management_oops_do)) {
185 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ManagementRoots, worker_id);
186 Management::oops_do(strong_roots);
187 }
188 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_jvmti_oops_do)) {
189 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JVMTIRoots, worker_id);
190 JvmtiExport::oops_do(strong_roots);
191 }
192 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) {
193 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id);
194 SystemDictionary::oops_do(strong_roots);
195 }
196 if (jni_weak_roots != NULL) {
197 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIWeakRoots, worker_id);
198 AlwaysTrueClosure always_true;
199 _weak_processor_task.work<AlwaysTrueClosure, OopClosure>(worker_id, &always_true, jni_weak_roots);
200 }
201
202 if (ShenandoahStringDedup::is_enabled() && weak_roots != NULL) {
203 ShenandoahStringDedup::parallel_oops_do(weak_roots, worker_id);
204 }
205
206 {
207 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id);
208 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_ObjectSynchronizer_oops_do)) {
209 ObjectSynchronizer::oops_do(strong_roots);
210 }
211 }
212
213 // All threads execute the following. A specific chunk of buckets
214 // from the StringTable are the individual tasks.
215 if (weak_roots != NULL) {
216 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringTableRoots, worker_id);
217 StringTable::possibly_parallel_oops_do(&_par_state_string, weak_roots);
218 }
219 }
|
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::vm, ShenandoahPhaseTimings::VMWeakRoots}
58 };
59
60 STATIC_ASSERT(sizeof(phase_mapping) / sizeof(PhaseMap) == WeakProcessorPhases::phase_count);
61
62 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
63 ShenandoahPhaseTimings::Phase phase) :
64 _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
65 _srs(n_workers),
66 _par_state_string(StringTable::weak_storage()),
67 _phase(phase),
68 _coderoots_all_iterator(ShenandoahCodeRoots::iterator()),
69 _weak_processor_timings(n_workers),
70 _weak_processor_task(&_weak_processor_timings, n_workers),
71 _processed_weak_roots(false) {
72 heap->phase_timings()->record_workers_start(_phase);
73
74 if (ShenandoahStringDedup::is_enabled()) {
75 StringDedup::gc_prologue(false);
76 }
77 }
78
79 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
80 delete _process_strong_tasks;
81 if (ShenandoahStringDedup::is_enabled()) {
82 StringDedup::gc_epilogue();
83 }
84
85 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
86
87 if (_processed_weak_roots) {
88 assert(_weak_processor_timings.max_threads() == n_workers(), "Must match");
89 for (uint index = 0; index < WeakProcessorPhases::phase_count; index ++) {
90 weak_processor_timing_to_shenandoah_timing(phase_mapping[index]._weak_processor_phase,
91 phase_mapping[index]._shenandoah_phase,
92 worker_times);
93 }
94 }
95
96 ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
97 }
98
99 void ShenandoahRootProcessor::weak_processor_timing_to_shenandoah_timing(const WeakProcessorPhases::Phase wpp,
100 const ShenandoahPhaseTimings::GCParPhases spp,
101 ShenandoahWorkerTimings* worker_times) const {
102 if (WeakProcessorPhases::is_serial(wpp)) {
103 worker_times->record_time_secs(spp, 0, _weak_processor_timings.phase_time_sec(wpp));
104 } else {
105 for (uint index = 0; index < _weak_processor_timings.max_threads(); index ++) {
106 worker_times->record_time_secs(spp, index, _weak_processor_timings.worker_time_sec(index, wpp));
107 }
108 }
109 }
110
111 void ShenandoahRootProcessor::process_all_roots_slow(OopClosure* oops) {
112 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
113 CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
114
115 CodeCache::blobs_do(&blobs);
116 ClassLoaderDataGraph::cld_do(&clds);
117 Universe::oops_do(oops);
118 Management::oops_do(oops);
119 JvmtiExport::oops_do(oops);
120 JNIHandles::oops_do(oops);
121 WeakProcessor::oops_do(oops);
122 ObjectSynchronizer::oops_do(oops);
123 SystemDictionary::oops_do(oops);
124 StringTable::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
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 // All threads execute the following. A specific chunk of buckets
256 // from the StringTable are the individual tasks.
257 if (weak_roots != NULL) {
258 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringTableRoots, worker_id);
259 StringTable::possibly_parallel_oops_do(&_par_state_string, weak_roots);
260 }
261 }
|