1 /* |
1 /* |
2 * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved. |
2 * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved. |
3 * |
3 * |
4 * This code is free software; you can redistribute it and/or modify it |
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 |
5 * under the terms of the GNU General Public License version 2 only, as |
6 * published by the Free Software Foundation. |
6 * published by the Free Software Foundation. |
7 * |
7 * |
39 #include "memory/iterator.hpp" |
39 #include "memory/iterator.hpp" |
40 #include "memory/resourceArea.hpp" |
40 #include "memory/resourceArea.hpp" |
41 #include "runtime/thread.hpp" |
41 #include "runtime/thread.hpp" |
42 #include "services/management.hpp" |
42 #include "services/management.hpp" |
43 |
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 |
44 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers, |
63 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers, |
45 ShenandoahPhaseTimings::Phase phase) : |
64 ShenandoahPhaseTimings::Phase phase) : |
46 _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)), |
65 _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)), |
47 _srs(n_workers), |
66 _srs(n_workers), |
48 _par_state_string(StringTable::weak_storage()), |
67 _par_state_string(StringTable::weak_storage()), |
49 _phase(phase), |
68 _phase(phase), |
50 _coderoots_all_iterator(ShenandoahCodeRoots::iterator()), |
69 _coderoots_all_iterator(ShenandoahCodeRoots::iterator()), |
51 _weak_processor_task(n_workers) |
70 _weak_processor_timings(n_workers), |
52 { |
71 _weak_processor_task(&_weak_processor_timings, n_workers), |
|
72 _processed_weak_roots(false) { |
53 heap->phase_timings()->record_workers_start(_phase); |
73 heap->phase_timings()->record_workers_start(_phase); |
54 |
74 |
55 if (ShenandoahStringDedup::is_enabled()) { |
75 if (ShenandoahStringDedup::is_enabled()) { |
56 StringDedup::gc_prologue(false); |
76 StringDedup::gc_prologue(false); |
57 } |
77 } |
61 delete _process_strong_tasks; |
81 delete _process_strong_tasks; |
62 if (ShenandoahStringDedup::is_enabled()) { |
82 if (ShenandoahStringDedup::is_enabled()) { |
63 StringDedup::gc_epilogue(); |
83 StringDedup::gc_epilogue(); |
64 } |
84 } |
65 |
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 |
66 ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase); |
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 } |
67 } |
110 } |
68 |
111 |
69 void ShenandoahRootProcessor::process_all_roots_slow(OopClosure* oops) { |
112 void ShenandoahRootProcessor::process_all_roots_slow(OopClosure* oops) { |
70 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong); |
113 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong); |
71 CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations); |
114 CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations); |
191 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) { |
234 if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) { |
192 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id); |
235 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id); |
193 SystemDictionary::oops_do(strong_roots); |
236 SystemDictionary::oops_do(strong_roots); |
194 } |
237 } |
195 if (jni_weak_roots != NULL) { |
238 if (jni_weak_roots != NULL) { |
196 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIWeakRoots, worker_id); |
239 AlwaysTrueClosure always_true; |
197 AlwaysTrueClosure always_true; |
240 _weak_processor_task.work<AlwaysTrueClosure, OopClosure>(worker_id, &always_true, jni_weak_roots); |
198 _weak_processor_task.work<AlwaysTrueClosure, OopClosure>(worker_id, &always_true, jni_weak_roots); |
241 _processed_weak_roots = true; |
199 } |
242 } |
200 |
243 |
201 if (ShenandoahStringDedup::is_enabled() && weak_roots != NULL) { |
244 if (ShenandoahStringDedup::is_enabled() && weak_roots != NULL) { |
202 ShenandoahStringDedup::parallel_oops_do(weak_roots, worker_id); |
245 ShenandoahStringDedup::parallel_oops_do(weak_roots, worker_id); |
203 } |
246 } |